/* api */
import * as TaskApi from '@src/api/TaskApi.ts';
import * as CalendarApi from '@src/api/CalendarApi.ts';
import * as ArchiveApi from '@src/api/ArchiveApi';
import * as SettingTaskApi from '@src/api/SettingTaskApi.js';
/* util */
import { debounce } from 'lodash'
import AuthUtil from '@src/util/auth';
import { getRootWindow } from '@src/util/dom';
import TaskStateEnum from '@model/enum/TaskStateEnum.ts';
import Filter from '@src/filter/filter.js';
import { parse } from '@src/util/querystring';
import Platform from '@src/util/platform.ts';
import { isBasicEdition } from '@shb-lib/version'
import {
  storageGet,
  storageSet
} from '@src/util/storage';
import { ctiCallOut } from '@src/util/ctisdk';
import { checkButtonDisplayed } from '@src/util/dom';
import { safeNewDate } from '@src/util/time';
import * as Utils from '@src/component/form/util';
import { useComplementRelatedFieldDateType } from '@hooks/useComplementRelatedFieldDateType'
import { getUserGuideStorageBase, setUserGuideStorageBase } from '@src/util/guideStorage'
import { findComponentDownward } from '@src/util/assist'

/* component */
import CancelTaskDialog from './components/CancelTaskDialog.vue';
import PlanTimeDialog from './components/PlanTimeDialog.vue';
import CalendarPlanTimeDialog from './components/CalendarPlanTimeDialog.vue';
import ApproveTaskDialog from './components/ApproveTaskDialog.vue';
import TaskApproveSignature from "./components/TaskApproveSignature.vue"
import TaskAdvancedApprove from "./components/TaskAdvancedApprove.vue"
import ProposeApproveDialog from './components/ProposeApproveDialog.vue';
import ServiceReportDialog from './components/ServiceReportDialog.vue';

import SettlementProviders from './components/SettlementProviders.vue';

import SettlementDialog from './components/settlement/index.vue';
import settlementTab from './components/settlement/settlementTab.vue';

import TaskInfoRecord from './components/TaskInfoRecord.vue';
import TaskReceiptView from './components/TaskReceipt/View/TaskReceiptView.vue';
import TaskReceiptEditView from './components/TaskReceipt/Edit/TaskReceiptEditView.vue';
import TaskAccount from './components/TaskAccount.vue';
import TaskFeedback from './components/TaskFeedback';
import TaskCard from './components/TaskCard';
import TaskProTab from './components/TaskProTab.vue';
import TaskView from './components/TaskView.vue';
import TaskTimeDialog from './components/TaskTimeDialog.vue';
import TaskAllotModal from '@src/modules/task/components/TaskAllotModal/TaskAllotModal.tsx'
import TaskMaterialList from '@src/modules/task/view/components/TaskMaterial/TaskMaterialList.vue';
import BaseBarV3 from '@src/component/common/BaseTabBar/BaseTabBarV3.vue'
import BaseTileLayoutTabBar from '@src/component/common/BaseTabBar/BaseTileLayoutTabBar.vue'
import FaultTable from '@src/modules/task/editAllot/components/PartSeviceList/components/FaultTable.vue';

import WikiRecommend from '@src/modules/task/components/WikiRecommend'
import { BaseSelectUserModeEnum } from '@src/component/common/BaseSelectUser/model/enum'
import NoDataViewNew from '@src/component/common/NoDataViewNew';
import BbxTimezoneTimePicker from '@src/component/Bbx/TimezoneTimePicker'

/* enum */
import { TaskEventNameMappingEnum } from '@model/enum/EventNameMappingEnum.ts';
import TableNameEnum from '@model/enum/TableNameEnum.ts';
/* mixin */
import tourGuide from '@src/mixins/tourGuide'
import ThemeMixin from '@src/mixins/themeMixin/index.ts'
import TaskCustomNodeMixin from '@src/modules/task/view/mixins/task-custom-node-mixin.js'
// import layoutMixin from '@src/mixins/layoutMixin'

import { checkPreTaskIsComplete } from '@src/api/ProjectManage.ts'

const ENCRYPT_FIELD_VALUE = '***';

import { TASK_GUIDE_DETAIL } from '@src/component/guide/taskV2Store';
import { openTabForWikiCreate } from '@src/util/business/openTab';

import TaskStateProcessEnum from '@model/enum/TaskStateProcessEnum.ts'

import { getWikiConfig, getUserCardConfig } from '@src/api/SettingApi'
import { taskConvertWiki } from '@src/api/Repository'
import { searchProvideSettleAuth, closeApproveCheck, getTaskUser, checkNeedVipApprove } from '@src/api/TaskApi'

import { getRootWindowInitData } from '@src/util/window'
import { isCalendar } from '@src/util/CalendarUtil';
import { getOssUrl, getLocalesOssUrl } from '@src/util/assets'
const defaultAvatar = getOssUrl('/avatar.png')
import {enCodeAtText, getReceivers} from '@src/util/atText'
import { useTenantId, useRootUser } from '@hooks/useRootWindow.ts';
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum'
import { BaseTabBarUsualEnum, BaseTabBarCardTypeEnum, StorageHttpParamsForTerminalType, StorageHttpParamsForModuleType } from '@src/component/common/BaseTabBar/enum'
import { computedTabList } from '@src/util/tabBarUtils'
import { getStorageForDetailTabbar, setStorageForDetailTabbar, getRichTextContent } from '@src/api/SystemApi'
import i18n, {t} from '@src/locales'
import { haveFaceCheckGray } from '@src/util/grayInfo'

import SelectUser from './components/selectUser.vue'
/* service */
import { isConnectorCard } from '@service/CardService'

// time util
import { useFormTimezone, useStateSystemViewLayout, cutAtTextContent } from 'pub-bbx-utils'
const { disposeFormItemViewTime } = useFormTimezone()

import { PULL_GROUP_GUIDE } from '@src/component/guide/productV2Store';
import addressKeyToViewLanguage, { getCountryKey } from '@src/component/common/BaseAddressSwitch/addressNameMultiLanguage';
/* mixin */
import { VersionControlTaskMixin } from '@src/mixins/versionControlMixin'
import { cloneDeep } from '@src/util/type';

const taskViewImage1 = getOssUrl('/no_auth.png')
const taskViewImage2 = getLocalesOssUrl('/task/qualityApprove.png')
const taskViewImage3 = getLocalesOssUrl('/task/approving.png')


export default {
  name: 'task-detail-view',
  inject: ['initData', 'taskALlNode'],
  mixins: [
    tourGuide,
    ThemeMixin,
    // layoutMixin,
    VersionControlTaskMixin,
    TaskCustomNodeMixin,
  ],
  data() {
    return {
      taskLeftBarList: [
        {
          tabName: 'task-view',
          disabled: true,
          tabLabel: i18n.t('task.taskInfo'),
          tabShow: true,
          position: 'left',
        }
      ],
      tabPosition: '',
      baseLayout: 2,
      taskLayoutTabBarList: [],
      taskViewImage1,
      taskViewImage2,
      taskViewImage3,
      // 手动结算 Start
      isSettlementDialog:false,
      // 手动结算 End
      isShowIm: false, // 是否展示一键拉群按钮
      isButtonDisplayed: checkButtonDisplayed(),
      partField: [], // 安装产品和安装位置字段 博立定制
      pending: false,
      collapse: true,
      collapsing: false,
      canViewTask: !!this.initData?.canViewTask,
      task: {...this.initData?.task, isAllowUpdate: this.initData?.isAllowUpdate, qualityInfo: {qualityStartTime: '', qualityEndTime: '', qualityStatus: ''}} || {},
      taskState: { value: this.initData?.task?.state || '' },
      fields: [], // 工单表单字段
      // 回退工单弹窗
      backDialog: {
        visible: false,
        reason: ''
      },
      // 暂停工单弹窗
      pauseDialog: {
        visible: false,
        reason: ''
      },
      // 拒绝工单弹窗
      refuseDialog: {
        visible: false,
        reason: ''
      },
      // 时间轴弹窗
      timeDialog: {
        visible: false
      },
      backList: [], // 异常原因
      systemAdmin: '', // 是否 是系统管理员 判断是否可以跳转到系统页面配置
      receiptFields: [], // 自定义回执字段
      customerRelationTaskCountData: {}, // 客户关联工单数量
      hasCallCenterModule: localStorage.getItem('call_center_module') == 1,
      stateButtonData: [], // 工单当前状态下主操作按钮
      leftActiveTab: 'task-view',
      rightActiveTab: '',
      rightActiveTabItem:{},
      collapseDirection: '',
      popperOptions: {
        boundariesElement: 'viewport',
        removeOnDestroy: true
      },
      guideSearchModelSave: false,
      guideDropdownMenu: false,
      isGuide: false,
      // 显示详情向导
      showTaskDetailGuide: false,
      // 是否显示指派弹窗
      showAllotModal: false,
      checkBack: '',
      // 是否拥有日程管理权限
      isCalendar,
      // todo 日程是否存在冲突
      isConflict: false,
      nowGuideStep: '',
      archiveCount:0, // 归档工单数量
      wikiKeywords: [],

      relationWikiSetting: [],

      wikiTaskFunction: false,

      finishedStates: TaskStateProcessEnum.FINISHED.value,
      isToReceiptView: false,
      srPrintAuthority: {},
      provideSettleConfig: {},
      notNull: true, // 暂停原因是否必填
      taskConfigData:{},
      atUsers:[],
      tabBarList:[],
      rightTabBarLoading:false,
      tabLabelKey:BaseTabBarUsualEnum.TabBarListItemLabel,
      treeData:[
        {
          id: 1,
          label: i18n.t('task.detail.relatedPerson'),
          children: [{
            id: 2,
            userType: 2,
            label: i18n.t('task.taskTypes.allot.taskExecutor')
          }, {
            id: 3,
            userType: 3,
            label: i18n.t('task.taskTypes.allot.taskSynergies')
          },
          {
            id: 4,
            userType: 1,
            label: i18n.t('task.setting.taskTypeSetting.flow.components.taskCreator')
          }]
        }
      ],
      currLevel: 1,
      defaultProps:{
        children: 'children',
        label: 'label'
      },
      selectUserTypeList: [], // 选中的关联人
      userLoading: false,
      SettlementData: {},
      vipApproveSetting: {},
      serviceReportList: [],
      // 翻译后的国家省市区字段集合
      addressNameObj:{},
      formCellCount:1,
      sparePartCardList: [], // 备件清单中已经申领出库的备件
      intelligentConfig: {},
      approve:{},
      vipBtnSetting: {},
      btnType: '',
      approveAttachments: [], // 高级审批附件
      approveInfoParams: {},
      vipJson: {}, // 高级审批的attribute 字段
      fromVip:false
    }
  },
  computed: {
    approveButtonText() {
      return this.btnType === 'agree' ? i18n.t('common.base.agree') : i18n.t('common.base.refuse');
    },
    taskLayout() {
      return this.baseLayout
    },
    hidePartCollapse() {
      if(this.taskLayout === 1) return this.tabPosition === 'left' ? 'right' : 'left';
      return '';
    },
    // 是否开结算灰度
    providerSettleV2() {
      const RootWindow = getRootWindow(window)
      return RootWindow.grayAuth?.providerSettleV2 || false
    },
    isWhiteList() {
      if(getRootWindowInitData().tenantType == 2) {
        return getRootWindowInitData().WHITE_LIST
      }
      return true
    },
    /**
     * 是否为质保审批
     *  isDelete = 3&& inApprove=1  为质保审批中
     */
    isQualityApprove() {
      return this.task.isDelete === 3 && this.task.inApprove === 1
    },
    /**
     * 是否为撤回质保审批
     *  isDelete = 3&& inApprove=0 为撤回质保审批
     */
    withdrawQualityApprove() {
      return this.task.isDelete === 3 && this.task.inApprove === 0
    },
    /**
     * 是否显示质保审批按钮
     * 1.有审批权限
     * 2.是质保审批中的工单
     * 3.处于待分配和已指派的状态
     */
    allowQualityApprove() {
      return this.isQualityApprove && this.initData.canApprove
    },
    // 是否隐藏归档工单按钮
    isShowArchive() {
      return this.initData?.auth?.TASK_ARCHIVE === 3
    },
    // 是否允许创建
    allowCreate() {
      return this.initData?.auth?.VIP_INFO_CREATE
    },
    /**
     * 是否已归档
     */
    isArchive(){
      return this.task?.isDelete === 2
    },
    /**
    * @description 客户字段
    */
    customerField() {
      return this.fields.filter(f => f.fieldName === 'customer')[0];
    },
    /**
    * @description 客户字段配置
    */
    customerOption() {
      return this.customerField?.setting?.customerOption || {};
    },
    /* 是否可以查看客户详情 */
    canSeeCustomer() {
      return this.initData.canSeeCus;
    },
    /* 计划时间字段 */
    planTimeField() {
      return this.fields.filter(f => f.fieldName === 'planTime')[0];
    },
    /* 计划时间 */
    planTime() {
      let { isEncryptPlanTime, planTime } = this.task;

      if (planTime) {
        if (isEncryptPlanTime) return ENCRYPT_FIELD_VALUE;

        return disposeFormItemViewTime(this.planTimeField || {}, planTime)
      }

      return '';
    },
    /* 计划开始时间字段 */
    planStartTimeField() {
      return this.fields.filter(f => f.fieldName === 'planStartTime')[0];
    },
    /* 计划开始时间 */
    planStartTime() {
      let { isEncryptPlanTime, planStartTime } = this.task;

      if (planStartTime) {
        if (isEncryptPlanTime) return ENCRYPT_FIELD_VALUE;

        // 计划时间国际化处理
        return disposeFormItemViewTime(this.planStartTimeField || {}, planStartTime)
      }

      return '';
    },
    /* 计划完成时间字段 */
    planEndTimeField() {
      return this.fields.filter(f => f.fieldName === 'planEndTime')[0];
    },
    /* 计划完成时间字段 */
    calendarPlanTime() {
      return this.fields.some(f => f.fieldName === 'calendarPlanTime');
    },
    /* 计划完成时间 */
    planEndTime() {
      let { isEncryptPlanTime, planEndTime } = this.task;

      if (planEndTime) {
        if (isEncryptPlanTime) return ENCRYPT_FIELD_VALUE;

        return disposeFormItemViewTime(this.planEndTimeField || {}, planEndTime)
      }

      return '';
    },
    /* 服务内容字段 */
    serviceContentField() {
      return this.fields.filter(f => f.fieldName === 'serviceContent')[0];
    },
    /** 工单设置 */
    taskConfig() {
      return this.initData?.taskConfig || {};
    },
    /** 工单类型设置 */
    taskType() {
      return this.initData?.taskType || {};
    },
    /** 当前登录用户 */
    loginUser() {
      return this.initData.loginUser || {};
    },
    /* 该登录账户是否是工单负责人 */
    isExecutor() {
      let executor = this.task.executor || {};
      return executor.userId == this.loginUser.userId;
    },
    /* 该登录账户是否是工单创建人 */
    isCreator(){
      let createUser = this.task.createUser || {};
      return createUser.userId == this.loginUser.userId;
    },
    /* 该登录账户是否是工单协同人 */
    isSynergies() {
      let synergies = this.task.synergies || [];
      return synergies.some(synergies => synergies.userId === this.loginUser.userId);
    },
    /** 当前用户的权限 */
    permission() {
      return this.loginUser.authorities || {};
    },
    /* 工单编辑权限 */
    editAuth() {
      return this.hasAuth('TASK_EDIT');
    },
    /**
    * @description 工单是否被删除
    * 在工单删除时不允许做任何操作，只能查询
    * 所有操作的权限应该以此为基础
    */
    isDelete() {
      return this.task.isDelete === 1;
    },
    /* 工单是否在审批状态 */
    isApproving() {
      return this.task.inApprove == 1;
    },
    /* 工单是否在暂停状态 */
    isPaused() {
      return this.task.isPaused == 1;
    },
    /* 工单是否在草稿状态 */
    isDraft() {
      return this.task.isDelete == 5;
    },
    /* 工单是否是未完成状态 */
    unFinishedState() {
      let unfinishedStateArr = ['created', 'allocated', 'taskPool', 'accepted', 'refused', 'processing'];
      return unfinishedStateArr.indexOf(this.task.state) >= 0;
    },
    /* 工单是否是完成状态 */
    finishedState() {
      let finishedStateArr = ['finished', 'costed', 'closed'];
      return finishedStateArr.indexOf(this.task.state) >= 0;
    },
    /**
    * @description 是否显示编辑按钮
    * 1. 不是审批状态
    * 2. 且 不是暂停状态
    * 3. 且 工单允许编辑 canEditTask
    * 4. 且 工单允许修改 isAllowUpdate
    * 5. 满足以上条件就会显示编辑按钮 无论是否有工单编辑权限TASK_EDIT
    */
    allowEditTask() {
      return !this.isApproving && !this.isPaused && this.initData.canEditTask && this.initData.isAllowUpdate && !this.isDelete;
    },
    /**
    * @description 是否显示删除按钮
    * 1. 不是审批状态!this.isApproving剔除
    * 2. 且 不是暂停状态
    * 3. 且 有工单删除权限TASK_DELETE
    * 4. 且 工单允许删除 canDeleteTask
    */
    allowDeleteTask() {
      return !this.isPaused && this.hasAuth('TASK_DELETE') && this.initData.canDeleteTask && !this.isDelete;
    },
    /**
    * @description 是否显示回退工单按钮
    * 1. 不是审批状态
    * 2. 且 工单是已完成状态
    * 3. 且 工单编辑设置开启了允许退回工单回执taskConfig.taskRollBack
    * 4. 且 允许回退工单 canRollBack
    */
    allowBackTask() {
      return !this.isApproving && this.task.state === 'finished' && this.taskConfig.taskRollBack && this.initData.canRollBack;
    },
    /**
    * @description 是否显示取消工单按钮
    * 1. 当前登录用户有工单编辑权限TASK_EDIT
    * 2. 不是审批状态!this.isApproving剔除
    * 3. 且 不是暂停状态
    * 4. 且 工单是未完成状态
    * 5. 且 允许取消工单 canOffTask
    */
    allowCancelTask() {
      // return this.editAuth && !this.isApproving && !this.isPaused && this.initData.canOffTask && this.unFinishedState;
      return this.initData.canOffTask && !this.isDraft
    },
    /**
    * @description 是否显示接单按钮
    * 1. 不是审批状态
    * 2. 且 工单状态是工单池
    */
    allowPoolTask() {
      return !this.isApproving && this.task.state === 'taskPool' && !this.withdrawQualityApprove;
    },
    /**
    * @description 是否显示暂停按钮
    * 1. 不是审批状态
    * 2. 且 不是暂停状态
    * 3. 且 工单状态是created/allocated/accepted/processing其中一种
    * 4. 且 允许暂停工单 canPause
    */
    allowPauseTask() {
      let stateArr = ['created', 'allocated', 'accepted', 'processing'];
      return !this.isApproving && !this.isPaused && this.initData.canPause && !this.withdrawQualityApprove && stateArr.indexOf(this.task.state) >= 0;
    },
    /**
    * @description 是否显示继续按钮
    * 1. 不是审批状态
    * 2. 且 是暂停状态
    * 3. 且 允许暂停工单 canPause
    */
    allowGoOnTask() {
      return !this.isApproving && this.isPaused && this.initData.canPause && !this.withdrawQualityApprove;
    },
    /**
    * @description 是否显示接受按钮
    * 1. 当前登录用户是工单负责人
    * 2. 不是审批状态
    * 3. 且 不是暂停状态
    * 4. 且 工单是已指派状态
    */
    allowAcceptTask() {
      return this.isExecutor && !this.isApproving && !this.isPaused && this.task.state === 'allocated';
    },
    /**
    * @description 是否显示拒绝按钮
    * 1. 满足显示接受按钮判断逻辑
    * 2. 且 工单设置中开启了允许工单负责人拒绝工单
    */
    allowRefuseTask() {
      return this.allowAcceptTask && this.taskConfig.taskRefuse;
    },
    /**
    * @description 是否显示开始按钮
    * 1. 当前登录用户是工单负责人
    * 2. 不是审批状态
    * 3. 且 不是暂停状态
    * 4. 且 工单状态是accepted
    * 5. 且 工单类型设置中流程设置开启了开始流程节点
    */
    allowStartTask() {
      return this.isExecutor && !this.isApproving && !this.isPaused && this.task.state === 'accepted' && this.taskType?.flowSetting?.start?.state;
    },
    /** 
    * @description 是否显示打卡出发按钮
    */
    showSetOutButton() {
      return this.initData.showSetOutButton;
    },
    /** 
    * @description 是否显示指派按钮
    * 1. 当前登录用户有指派工单权限TASK_DISPATCH
    * 2. 不是审批状态
    * 3. 且 不是暂停状态
    * 4. 且 工单状态是created/refused/taskPool其中一种
    */
    allowAllotTask() {
      let stateArr = ['created', 'refused', 'taskPool'];
      return this.hasAuth('TASK_DISPATCH') && !this.isApproving && !this.withdrawQualityApprove && !this.isPaused && stateArr.indexOf(this.task.state) >= 0;
    },
    /**
    * @description 是否显示转派按钮
    * 1. 不是审批状态
    * 2. 且 不是暂停状态
    * 3. 且 工单状态是allocated/accepted/processing其中一种
    * 4. 允许转派 canRedeploy
    */
    allowRedeployTask() {
      let stateArr = ['allocated', 'accepted', 'processing'];
      return !this.isApproving && !this.isPaused && this.initData.canRedeploy && stateArr.indexOf(this.task.state) >= 0;
    },
    /**
    * @description 是否显示关闭工单按钮
    */
    allowCloseTask() {
      return this.initData.canCloseTask
    },
    /**
    * @description 是否显示打印工单按钮
    * 1. 工单类型设置开启了启用打印功能
    * 2. 满足以上条件即会显示打印工单
      (1)曾打印 task.oncePrinted == 1 样式有区别
    */
    allowPrintTask() {
      let { printTask } = this.taskType?.options || {};
      return (printTask || printTask == null) && !this.isDraft;
    },
    /**
    * @description 是否显示服务报告按钮
    * 1. 工单类型设置开启了发送服务报告
    * 2. 且 工单是已完成状态
    */
    allowServiceReport() {
      let { serviceReport } = this.taskType.options || {};
      return (serviceReport || serviceReport == null) && this.finishedState;
    },
    /**
     * 是否允许工单分享
     */
    allowTaskShare() {
      return this.initData?.taskShareButton?.insideShare
    },
    /** 服务报告是否使用系统模板 */
    srSysTemplate() {
      return this.taskType?.options?.srSysTemplate;
    },
    /**
    * @description 是否显示审批按钮
    * 1. 是审批状态
    * 2. 且 当前工单是否存在审批unFinishedAppr.id
    * 3. 允许审批 canApprove
    */
    allowApprove() {
      return this.isApproving && this.unFinishedAppr.id && this.initData.canApprove && !this.withdrawQualityApprove && !this.isQualityApprove;
    },

    /**
    * @description 是否显示高级审批设置相关按钮
    * 1. 是审批状态
    * 2. 且 当前工单是否存在高级审批unFinishedAppr.processorInstanceId
    * 3. 允许审批 canApprove
    */
    allowVipApprove() {
      return this.isApproving && this.unFinishedAppr.id && this.unFinishedAppr.processorInstanceId && !this.withdrawQualityApprove && !this.isQualityApprove;
    },
    /**
    * @description 是否显示撤回审批按钮
    * 1. 是审批状态
    * 2. 且 当前工单是否存在审批unFinishedAppr.id
    * 3. 允许撤回审批 canOffAppr
    */
    allowoffApprove() {
      return this.isApproving && this.unFinishedAppr.id && this.initData.canOffAppr;
    },

    // 是否是高级审批模式
    isVipApprove() {
      return this.isApproving && this.unFinishedAppr.processorInstanceId && this.initData.canApprove && !this.withdrawQualityApprove && !this.isQualityApprove;
    },

    /** 工单审批数据 */
    unFinishedAppr() {
      return this.initData.unFinishedAppr || {};
    },
    /**
    * @description 是否显示回执完成按钮
    * 1. 当前登录用户是工单负责人
    * 2. 不是审批状态
    * 3. 且 不是暂停状态
    * 4. 且 (如果工单状态是accepted且工单流程设置禁用了开始流程 或 如果工单状态是processing且工单流程设置开启了开始流程)
     *5. 且customNodeBtnShow为false，因为到达自定义节点的时候，状态没有改变，所有加个判断
    */
    allowFinishTask() {
      let startFlow = this.taskType?.flowSetting?.start?.state;
      let { state } = this.task;

      return this.isExecutor && !this.isApproving && !this.isPaused && ((state === 'accepted' && !startFlow) || (state === 'processing' && startFlow)) && !this.customNodeBtnShow;
    },
    /**
     * @description 是否显示 [审核结算]tab
     * 1. 工单是已完成状态
     * 2. 且 工单是否结算过
     * 3. 且 根据工单结算设置结算信息查看权限
      (1)仅有审核结算权限可见“onlyHasBalanceAuthiroty”且登录账户有工单审核结算权限TASK_AUDIT
      (2)或 有工单查看权限即可见“hasTaskViewAuthiroty”且(登录账户有工单审核结算权限TASK_AUDIT或有工单查看权限TASK_VIEW)
      (3)或 有工单编辑权限即可见“hasTaskEditAuthiroty”且(登录账户有工单审核结算权限TASK_AUDIT或有工单编辑权限TASK_EDIT)
    */
    viewBalanceTab() {
      let { isSettled } = this.task;
      let balanceViewAuthiroty = this.taskConfig?.taskBalanceConfig?.balanceViewAuthiroty;

      return (
        this.finishedState
        && (isSettled == 0 || isSettled == 1)
        && ((balanceViewAuthiroty === 'onlyHasBalanceAuthiroty' && this.hasAuth('TASK_AUDIT'))
          || (balanceViewAuthiroty === 'hasTaskViewAuthiroty' && this.hasAuth(['TASK_AUDIT', 'TASK_VIEW']))
          || (balanceViewAuthiroty === 'hasTaskEditAuthiroty' && this.hasAuth(['TASK_AUDIT', 'TASK_EDIT'])))
      );
    },
    /**
     * @description 是否显示 [客户评价]tab
     * 1. 评价时间不为null 或 未回访过
     * 2. 且 根据客户满意度设置中客户评价信息查看权限
      (1)仅有回访权限可见“onlyHasReviewAuthiroty”且登录账户有工单回访权限TASK_FEEDBACK
      (2)或 有工单查看权限即可见“hasTaskViewAuthiroty”且(登录账户有工单审核结算权限TASK_FEEDBACK或有工单查看权限TASK_VIEW)
      (3)或 有工单编辑权限即可见“hasTaskEditAuthiroty”且(登录账户有工单审核结算权限TASK_FEEDBACK或有工单编辑权限TASK_EDIT)
    */
    viewFeedbackTab() {
      let { reviewTime, isEvaluated, isReviewed } = this.task;
      let reviewViewAuthiroty = this.initData?.evaluateConfig?.reviewViewAuthiroty;

      return (
        (reviewTime != null || isEvaluated == 0 || isEvaluated == 1 || isReviewed == 0 || isReviewed == 3)
        && ((reviewViewAuthiroty === 'onlyHasReviewAuthiroty' && this.hasAuth('TASK_FEEDBACK'))
          || (reviewViewAuthiroty === 'hasTaskViewAuthiroty' && this.hasAuth(['TASK_FEEDBACK', 'TASK_VIEW']))
          || (reviewViewAuthiroty === 'hasTaskEditAuthiroty' && this.hasAuth(['TASK_FEEDBACK', 'TASK_EDIT'])))
      );
    },
    /**
    * @description 非自定义回执
    * 默认工单且未开启自定义回执(老功能)
    */
    notCustom() {
      let receiptConfig = this.initData.receiptConfig || {};
      return !receiptConfig?.customReceipt && this.task.templateId == '1';
    },
    /**
    * @description 显示回执
    * 1. 工单状态是finished/costed/closed其中一种
    * 2. 或 满足显示回执按钮条件
    * 3. 或 工单处于完成审批中
    */
    showReceipt() {
      return this.finishedState || this.approvingForComplete;
    },
    /**
    * @description 是否显示 [回执信息]tab
    * 满足显示回执条件后，回执表单自定义字段length=0且时隐藏tab(不包含默认工单且未开启自定义回执)
    */
    viewReceiptTab() {
      // 回执表单是否包含字段
      let hasField = this.receiptFields.length > 0;
      return this.showReceipt && hasField;
    },
    // 处理完成审批
    approvingForComplete() {
      let { canEditTask } = this.initData;
      let canLookCompleteReceipt = canEditTask || this.permission.VIP_APPROVE == 3;

      // TODO 国际化待办
      return this.isApproving && this.unFinishedAppr && this.unFinishedAppr.action == '完成' && (this.isExecutor || this.initData.canApprove || canLookCompleteReceipt);
    },
    /**
    * @description 允许修改协同人
    * 1. 工单状态
    * 2. PC端开启允许修改协同人，并且是负责人
    * 3. 工单创建人或者允许编辑工单
    */
    allowEditSynergy() {
      let state = ['allocated', 'accepted', 'processing', 'taskPool'];
      let allowModify = this.taskConfig.taskSynergy;

      return state.indexOf(this.task.state) >= 0 && ((allowModify && this.isExecutor) || this.isCreator || this.editAuth);
    },
    /**
    * @description 工单信息中计划时间是否可以修改
    * 1. 工单状态是accepted/processing其中一种
    * 2. 当前登录账户是工单负责人
    * 3. 工单设置允许修改计划时间
    */
    allowModifyPlanTime() {
      let stateArr = ['accepted', 'processing'];
      let { state } = this.task;
      // console.log('工单信息中计划时间是否可以修改',this.isExecutor,this.taskConfig.taskPlanTime,state)
      return this.isExecutor && this.taskConfig.taskPlanTime && stateArr.indexOf(state) >= 0;
    },
    /**
    * @description 是否显示DING按钮
    * 1. 有工单查看权限 canViewTask
    * 2. 且 在钉钉pc端
    * 3. 且 有工单负责人
    * 4. 且 工单不是关闭状态closed
    */
    allowDing() {
      // 是否有负责人
      let { state, executor } = this.task;
      let hasExecutor = executor && executor.userId;
      let allowDing = false;

      try {
        // fix:17651 判断是否在钉钉桌面端，使用最新的判断条件inDingTalk就行
        const inDingTalk = Platform.inDingTalk()
        allowDing = this.initData.canViewTask && inDingTalk && state != 'closed' && hasExecutor;
      } catch (error) {
        console.warn('Caused: TaskView allowDing -> error', error)
      }

      return allowDing;
    },
    /**
    * @description 是否显示复制工单按钮
    * 1. 当前登录用户有新建工单权限TASK_ADD
    * 2. 允许复制工单 canCopyTask
    */
    allowCopyTask() {
      return this.hasAuth('TASK_EDIT') && this.initData.canCopyTask && !this.isDraft;
    },
    /**
    * @description 是否显示回访按钮
    * 1. 当前登录账户有工单回访权限TASK_FEEDBACK
    * 2. 且 不是审批状态
    * 3. 且 未回访过
    */
    allowReviewTask() {
      let { inApprove, isReviewed, isReview } = this.task;
      let feedbackAuth = this.hasAuth('TASK_FEEDBACK');

      return feedbackAuth && inApprove != 1 && (isReviewed == 0 || isReviewed == 3) && (isReview == 0 || isReview == 3);
    },
    /**
    * @description 是否显示结算按钮
    * 1. 工单状态是已完成finished
    * 2. 且 不是审批状态
    * 3. 且 未结算过
    * 4. 且 允许回退工单 canRollBack
    */
    allowBalanceTask() {
      let { state, inApprove, isSettled } = this.task;

      return state === 'finished' && inApprove != 1 && isSettled == 0 && this.initData.canRollBack;
    },
    /**
    * @description 是否显示附加组件tab
    */
    viewTaskCardTab() {
      return this.initData?.cardInfo?.length > 0;
    },
    /**
    * @description 附加组件tab
    */
    taskCards() {
      // 多选格式调整
      this.initData.cardInfo.forEach(card => {
        card.fields = Utils.migration(card.fields || []);
      })

      // 过滤没有权限的附加组件
      return this.initData.cardInfo.filter(card => {

        let { canWrite, canRead, canCreate, canDelete } = card;

        const isHaveAuth = (canWrite || canRead || canCreate || canDelete)
        const isHaveFields = card.fields.length

        // 是否为连接器附加组件，连接器附加组件里面不存字段列表，所以只判断权限就可以
        if (isConnectorCard(card)) {
          return isHaveAuth
        }

        return isHaveAuth && isHaveFields

      })
    },
    /**
    * @description 是否显示物料清单tab
    */
    viewTaskMaterialTab() {
      const RootWindow = getRootWindow(window);
      return RootWindow?.grayAuth?.taskMarteriaList;
    },
    /**
    * @description 物料配置
    */
    materialInfo() {
      return this.initData?.materialInfo || {}
    },
    /**
    * @description 是否显示故障清单tab
    */
    viewTaskFaultTab() {
      return (this.initData?.cardInfo || []).includes(x => x.specialfrom === '故障清单');
    },
    /**
    * @description 质保状态
    */
    warrantyStatus() {
      let { warrantyStatus } = this.materialInfo

      if (warrantyStatus) return warrantyStatus === 'IN' ? 0 : 1

      return warrantyStatus
    },
    /** 子组件所需的数据 */
    propsForSubComponents() {
      return {
        task: this.task,
        auth: this.permission,
        receiptFields: this.receiptFields,
        isFinishApproving: this.approvingForComplete,
        isExecutor: this.isExecutor,
        isSynergies: this.isSynergies,
        linkman: {
          lmName: this.lmName,
          lmPhone: this.lmPhone
        },
        address: this.address,
        collapseDirection:this.collapseDirection,
        isArchive:this.isArchive,
        warrantyStatus: this.warrantyStatus
      }
    },
    /**
    * @description 客户
    */
    customer() {
      return this.task?.customer || {};
    },
    /**
    * @description 允许打开客户详情
    */
    allowOpenCustomerView() {
      return !this.isEncryptField(this.customer.name) && this.canSeeCustomer;
    },
    /**
    * @description 联系人
    */
    lmName() {
      let lmName = this.task.tlmName || '';

      if (lmName) return this.isEncryptField(lmName) ? ENCRYPT_FIELD_VALUE : lmName;

      return '';
    },
    /**
    * @description 联系电话
    */
    lmPhone() {
      let lmPhone = this.task.tlmPhone || '';

      if (this.lmName) return this.isEncryptField(this.lmName) ? ENCRYPT_FIELD_VALUE : lmPhone;

      return '';
    },
    /**
    * @description 显示拨打电话
    * 1. 开通呼叫中心
    * 2. 且联系人未加密
    */
    showCallPhone() {
      let notEncrypt = !this.isEncryptField(this.lmName);
      const hasCallAuth = !!getRootWindow(window).CTI
      return this.lmPhone && this.hasCallCenterModule && notEncrypt && hasCallAuth;
    },
    /**
    * @description 地址
    */
    address() {
      let { validAddress, taddress, isEncryptTaddress } = this.task;

      if (validAddress) return isEncryptTaddress ? ENCRYPT_FIELD_VALUE : Filter.prettyAddress(this.addressNameObj,'-');

      return '';
    },
    /**
    * @description 显示查看地图icon
    * 1. 地址未加密
    */
    showMap() {
      let { taddress, isEncryptTaddress } = this.task;
      return !isEncryptTaddress;
    },
    /**
    * @description 是否显示客户关联的工单数量
    * 1. 客户存在
    * 2. 且全部数量>0
    * 3. 客户未加密
    */
    showCustomerRelationTaskCount() {
      let { all } = this.customerRelationTaskCountData;
      return this.customer?.id && Number(all) > 0 && !this.isEncryptField(this.customer.name);
    },
    /**
    * @description 工单状态
     * 自定义节点：需要取自定义节点的状态
    */
    stateText() {
      return (this.customStateName && !this.isPaused) ? this.customStateName : TaskStateEnum.getNameForTask(this.task);
    },
    /**
    * @description 工单状态颜色
    */
    stateColor() {
      return (this.customStateName && !this.isPaused) ? {color: '#FF9100', bgColor: 'rgba(255, 145, 0)'} : TaskStateEnum.getColorForTask(this.task);
    },
    messageConfig() {
      return this.initData?.messageConfig || {};
    },
    showTaskRecordTemplate() {
      return this.messageConfig.taskRemark === true
    },
    /* 是否显示服务报告 根据版本控制的 */
    isShowReport() {
      return this._isShowTaskServiceReport
    },
    /* 是否开始新工单的新指派 */
    isRestructAllot() {
      return this.initData?.restructAllot === true
    },
    /* 附加组件 */
    cardInfo() {
      return this.initData?.cardInfo || [];
    },
    /**
    * @description 暂停原因是否设置为必填
    */
    isReasonRequired() {
      return this.notNull
    },
    isReasonRequiredPlaceholder() {
      return this.isReasonRequired ? `[${this.$t('common.base.isRequire')}]` : `[${this.$t('common.base.optional')}]`
    },
    /**
    * @description 满意度灰度
    * 开启时(true)隐藏满意度字段
    */
    satisfaction() {
      const RootWindow = getRootWindow(window);
      return RootWindow?.grayAuth?.satisfaction;
    },
    /* 是否为基础版 */
    isBasicEdition() {
      return isBasicEdition()
    },
    // 呼叫中心来源数据
    callCenterSourceData(){
      return {
        sourceTypeId:this.task.id,
        sourceType:'task',
        sourceTypeNo:this.task.taskNo
      }
    },
    // 是否开启人脸识别校验（开始工单）
    haveFaceStartCheck(){
      return this.taskType?.flowSetting?.start?.startByFaceId
    },
    // 是否开启人脸识别校验（完成工单）
    haveFaceFinishCheck(){
      return this.taskType?.flowSetting?.finish?.finishByFaceId
    },
    // 该工单负责人是否录入人脸信息
    userHaveFaceInfo(){
      return this.initData?.userFaceState == 1
    },
    haveFaceCheckGray(){
      return haveFaceCheckGray()
    },
    // 开启添加行灰度
    isShowCardMultiSave() {
      const RootWindow = getRootWindow(window)
      return RootWindow?.grayAuth?.CARD_MULTI_SAVE;
    },
    // 故障清单tab
    faultListTab() {
      let tab = this.cardInfo?.find(item => item.specialfrom == '故障清单')
      return tab;
    },
    // 新建权限
    addFaultAuth() {
      return this.faultListTab?.canCreate || false
    },
    // 删除权限
    deleteFaultBtn() {
      return this.faultListTab?.canDelete || false
    },
    // 编辑权限
    editFaultBtn() {
      return this.faultListTab?.canWrite || false
    },
    // 是否显示更多按钮
    moreBtnEnable() {
      // 1.分享按钮 2.打印 3.ding 4.复制 5.删除 6.编辑 7.一键拉群
      return this.allowTaskShare || (this.allowPrintTask && this.isButtonDisplayed) || this.allowDing ||
          (this.allowCopyTask && !this.isArchive) || this.allowDeleteTask || (this.allowEditTask && !this.isArchive) || this.isShowIm
    },
  },
  methods: {
    head(src) {
      if (!src) return defaultAvatar
      return src
    },
    upload(queue){
      this.$set(this, 'approveAttachments', queue)
    },

    async remove(file){
      if(!await this.$platform.confirm(this.$t('common.form.preview.file.deleteFileTips'))) return;

      let index = -1;
      for(let i = 0; i < this.approve.attachments.length; i++){
        let f = this.approve.attachments[i];
        if(f.url == file.url){
          index = i;
          break;
        }
      }
      if(index >= 0) this.approve.attachments.splice(index, 1);
    },
    getNodeData() {
      return this.vipJson.cells
        .filter(item => item.shape === 'approve-node')
        .map((item) => {
          return {
            nodeTemplateId: item.id,
            nodeName: item.data.name
          }
        });
    },

    submit(params) {
      let approveId = this.unFinishedAppr.id
      let approveRemark = this.approve.approveRemark
      let approveAttachments= this.approveAttachments

      if (this.fromVip) {

        // 所有的审批节点数据
        let vipApproveFlowArr = this.getNodeData()
        const { currentaskId, currentNodeName,  currentNodeTemplateId} = this.approveInfoParams

        let vipParams = {
          id: approveId,
          approveTaskId: currentaskId,
          button: this.btnType,
          applyMessage: approveRemark,
          nodeName: currentNodeName,
          nodeTemplateId: currentNodeTemplateId,
          vipApproveFlow: vipApproveFlowArr,
          attachments: approveAttachments,
          ...params,
        }
        
        let receivers = ''
        let query = ''
        receivers = getReceivers(vipParams.approveRemark, vipParams.atUsers)
        let queryData = {
          receivers,
          tenantId: useTenantId().value,
          content: cutAtTextContent(vipParams.approveRemark),
          sendUserName: useRootUser().value?.displayName,
          bizId: this.approve.objId,
          bizNo: this.task.taskNo || this.approve.objNo,
          md: this.$t('common.base.task')
        };
        query = '?';
        for (let i in queryData) {
          query += `&${i}=${queryData[i]}`;
        }
        this.pending = true;

        // 工单审批
        this.taskVipApproveSubmit(vipParams, query)
      }
    },
    // 工单审批提交接口
    taskVipApproveSubmit(vipParams, query) {
      TaskApi.saveVipApprove(vipParams, query)
        .then((res) => {
        if (res.success) {
          this.$platform.notification({
            type: 'success',
            title: this.$t('task.tip.approveTip5')
          })
          let fromId = window.frameElement.getAttribute('fromid');
          this.$platform.refreshTab(fromId);

          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch((err) => {
        this.pending = false;
      });
    },
    openBaseLayoutModal() {
      this.$refs.bizLayoutModal.open()
    },
    changeTaskDetailLayout(type, columns) {
      this.leftActiveTab = 'task-view' 
      this.baseLayout = type
      this.tabPosition = 'left'
      if(type === 2) {
        this.rightActiveTab = 'record' 
      }
      this.formCellCount = columns * 1
    },
    // 手动结算 Start
    saveDataSettlement(value){
      this.SettlementData = value
    },
    OpenSettlement(){
      this.isSettlementDialog = true
    },
    CloseSettlement(){
      this.isSettlementDialog = false
    },
    SettlementSave(){
      location.reload();
    },
    // 手动结算 End
    head(src) {
      if (!src) return defaultAvatar
      return src
    },
    async createGroudChat() {
      let defaultUserList = []

      // 获取所有选中的人员
      let res = await getTaskUser({ taskId: this.task.id })
      if(res.code === 0) {
        defaultUserList = res.result
        this.selectUserTypeList = []
        defaultUserList.forEach((item) => {
          if (Array.isArray(item.userTypeList) && item.userTypeList.includes(2)) {
            this.selectUserTypeList.push(item)
          }
        })
        this.selectUserTypeList.forEach((item) => {
          this.$set(item, 'userTypeFrom', 2)
          this.$set(item, 'typeId', 1)
        })
      }
      // 登陆人
      let {displayName, head, userId, staffId} = this.loginUser
      let loginUserObj = {
        displayName,
        head,
        userId,
        staffId
      }
      defaultUserList.push(loginUserObj)

      // 去重人员重复
      let selectobj = {};
      let selectedUser = defaultUserList.reduce((cur, next) => {
        selectobj[next.userId] ? '' : selectobj[next.userId] = true && cur.push(next);
        return cur;
      }, [])

      let options = {
        title: i18n.t('system.notificationCenter.text6'),
        max: 10, // [选填]最大人数：当值小于等于0或者不填时，不对选择人数做限制，max值为1时单选，大于1时多选
        selectedUsers: selectedUser, // [选填] 已选人员 每个人员必须包括userId,displayName,staffId,head这四个属性，只有带max大于1时生效
        mode: BaseSelectUserModeEnum.Filter,
        isShowDynamic: true,
        DynamicTabName: i18n.t('component.baseSelectUser.dynamicGain'),
        currentTabType: 'dynamic', // 默认选中的标签
        // 自定义渲染动态获取内容
        renderDynamicContent: (h, context) => {
          const isSelectedByUserId = context.isSelectedByUserId
          return (
            <div class="base-select-user-select-panel-container">
              <div class='base-select-user-select-panel-left'>
                <el-tree
                  class="tree-user"
                  data={this.treeData}
                  default-expand-all
                  node-key="id"
                  ref="tree"
                  highlight-current
                  current-node-key={2}
                  onNode-click={this.getTaskTypeUser}
                  props={this.defaultProps}>
                </el-tree>
              </div>
              <div class="base-select-user-select-panel-right">
                <div class="base-select-user-service-provider-right" v-loading={this.userLoading}>
                  <div class="base-select-user-infinite-scroll-user">
                    <div class='base-select-user-user-list'>
                      {!this.userLoading && this.selectUserTypeList.length > 0 && this.selectUserTypeList.map((item) => {
                        return (
                          <SelectUser
                            value={item}
                            selected={isSelectedByUserId(item.userId)}
                            onLabelChange={(e) => {
                              this.labelChange(e, context, isSelectedByUserId(item.userId))
                            }}
                          >
                          </SelectUser>
                        )
                      })}
                      {
                        !this.userLoading && this.selectUserTypeList.length === 0 && (
                          <div class='task-no-data'>
                            <NoDataViewNew
                              notice-msg="暂无数据"
                            ></NoDataViewNew>
                          </div>
                        )
                      }
                    </div>
                  </div>

                </div>
              </div>
            </div>
          )
        }
      };
      this.$fast.select.multi.user(options).then(res => {
        if(res.status != 0) return
        // 群名规则
        let groupName = `${this.task.customer.name}${this.task.templateName}沟通群`
        let selectUserList = res?.data?.users || [];
        // 所有选中的userId
        let memberUserIdList = []
        if (selectUserList.length > 0) {
          memberUserIdList = selectUserList.map(v => v.userId)
        }

        let params = {
          memberUserIdList,
          groupName,
          bizType: 'task',
          bizId: this.task.id,
        }

        // 请求创建im接口
        const RootWindow = getRootWindow(window);
        RootWindow.open_insideIM(params)

      })
        .catch(err => {
          console.warn(err)
        })
    },

    labelChange(val, context, isSelected) {
      if (isSelected) {
        context.$emit('remove', val)
      } else {
        context.$emit('add', val)
      }
    },

    async getTaskTypeUser(data) {
      this.userLoading = true
      this.selectUserTypeList = [] // 数据切换之前清除
      let res = await getTaskUser({ taskId: this.task.id, userType: data.userType || 2})
      this.userLoading = false
      if(res.result && res.result.length > 0) {
        this.selectUserTypeList = res.result
        this.selectUserTypeList.forEach((item) => {
          //  默认都是选中的
          // this.$set(item, 'checked', true)
          this.$set(item, 'userTypeFrom', data.userType)
          this.$set(item, 'typeId', 1)

        })
      }
    },
    // 获取工单配置数据，用来拿到当前流程的工单审批时是否必填备注信息
    async getTaskConfig(){
      const { taskConfig } = await TaskApi.getTaskConfig();
      if (taskConfig) {
        this.taskConfigData = taskConfig
      }
    },
    getUserCardConfig() {
      getUserCardConfig().then(res => {
        if(res.success) {
          this.isShowIm = res.data.showIm && res.data.authIm
        }
      }).catch(err => {
        console.error(err)
      })
    },

    // 获取用于知识库推荐的字段
    taskConvertWiki() {
      return taskConvertWiki({
        taskId: this.task.id,
        taskTypeId: this.task.templateId
      }).then(res => {
        if(res.code === 0) {
          let arr = [...(res.result?.cardList || []), ...(res.result?.fieldList || [])]
          return this.wikiKeywords = arr.filter(v => v.content).map(v => v.content)
        }
      }).catch(err => {
        console.log(err)
      })
    },
    // 获取工单类型中知识库关联字段配置
    getConfig(templateId) {
      TaskApi.getConfig({
        typeId: templateId
      }).then(res => {
        if(res.succ) {
          let data = res.data?.wikiSetting || []
          // data = data.map(v => v.fieldName).filter(v => v)
          this.relationWikiSetting = data
          this.intelligentConfig = res.data.intelligentConfig
        }
      }).catch(err => {
        console.error(err)
      })
    },

    // 获取知识库设置中的工单服务配置
    getWikiConfig() {
      getWikiConfig().then(res => {
        if(res.succ) {
          this.wikiTaskFunction = res.data.taskFunction
        }
      }).catch(err => {
        console.error(err)
      })
    },
    //
    async searchProvideSettleAuth() {
      try {
        let res = await searchProvideSettleAuth({ taskId: this.task.id })
        if(res.code === 0) {
          this.provideSettleConfig = res.result;
        }
      } catch (error) {
        console.error('search provide settle auth', error);
      }
    },
    // 从详情字段中获取标签
    // getLabels() {
    //   let arr = []
    //   this.relationWikiSetting.forEach(field => {
    //     if(field.cardId) { // 寻找附加组件的字段并获取标签
    //       let fields = this.task?.cardInfo?.find(v => v.cardId === field.cardId)?.attribute || {}
    //       for (let key of Object.keys(fields)) {
    //         if (key.startsWith('field_')) {
    //           let value = fields[key]
    //           // this.searchTags(value, arr)
    //           if(!arr.includes(value)) arr.push(value)
    //         }
    //       }
    //     } else {// 自定义表单项
    //       let value = this.task?.attribute ? this.task?.attribute[field.fieldName] : ''
    //       if (!value) return
    //       // this.searchTags(value, arr)
    //       if(!arr.includes(value)) arr.push(value)
    //     }
    //   })
    //   return this.wikiKeywords = arr
    // },
    // 搜索标签
    // searchTags(data, arr = []) {
    //   let tags = data.match(/#.*? /g)
    //   tags && tags.forEach(tag => {
    //     if(!arr.includes(tag)) arr.push(tag.slice(1, tag.length - 1))
    //   })
    //   return arr
    // },
    transToWiki() {
      openTabForWikiCreate({
        taskId: this.task.id,
        taskNo: this.task.taskNo,
        taskTypeId: this.task.templateId
      })
    },
    updateInfoRecord() {// 更新动态信息
      this.$refs.record ? this.$refs.record.initializeRecord() : '';
    },
    // 获取归档工单数量
    async getCount(){
      return Promise.resolve(true)
      // const params = {
      //   customerId:this.customer.id
      // }
      // const {code, message, result} = await ArchiveApi.getCount(params);
      // if(code === 0){
      //   this.archiveCount = result.archiveCount;
      // }else{
      //   this.$notify({
      //     title: i18n.t('common.base.fail'),
      //     message,
      //     type: 'error'
      //   });
      // }
    },
    // 关闭工单
     closeTask() {
      this.$confirm(i18n.t('task.tip.closeTaskTip'), i18n.t('task.closeTask'), {
        confirmButtonText: i18n.t('common.base.makeSure'),
        cancelButtonText: i18n.t('common.base.cancel'),
        type: 'warning'
      }).then(async () =>{

        // 先判断是否需要高级审批
        let approveParams = {
          taskId: this.task.id,
          action: 'close'
        }

        const approveResult = await checkNeedVipApprove(approveParams);
        if (approveResult?.success && approveResult?.result?.needVipApprove) {
          this.proposeApprove(approveResult?.result ?? {})
          return
        }

        closeApproveCheck({ id: this.task.id }).then(res => {
          if(res?.succ){
            this.refreshFromTab();
            location.reload();
            this.$message.success(i18n.t('task.tip.closeSucceed'))
            return
          }

          // TODO 需要审批判断改成errorCode
          if(!res.succ && Number(res.errorCode) == 10003) {
            this.proposeApprove(res.data)
            return
          }

          this.$notify({
            title: i18n.t('common.base.fail'),
            message: res.message,
            type: 'error'
          });
        })
      }).catch(()=>{})
    },
    // 工单归档
    archiveTask(){
      this.$confirm(i18n.t('task.tip.archiveTaskTip1'), i18n.t('task.taskPlaceOnFile'), {
        confirmButtonText: i18n.t('common.base.makeSure'),
        cancelButtonText: i18n.t('common.base.cancel'),
        type: 'warning'
      }).then(()=>{
        ArchiveApi.archiveTask({taskIds:[this.task.id]}).then(res=>{
          if(res.code === 0){
            this.refreshFromTab();
            location.reload();
            this.$message.success(i18n.t('task.tip.archiveSucceed'))
          }else{
            this.$notify({
              title: i18n.t('common.base.fail'),
              message: res.message,
              type: 'error'
            });
          }
        })
      }).catch(()=>{})
    },
    // 刷新from tab
    refreshFromTab() {
      let fromId = window.frameElement.getAttribute('fromid')
      this.$platform.refreshTab(fromId)
    },
    // 工单是否冲突校验
    async checkCalendarClash(){
      try {
        const params = {
          planStartTime: safeNewDate(this.planStartTime),
          planEndTime: safeNewDate(this.planEndTime),
          taskId: this.task.id
        };
        const res = await CalendarApi.calendarClashInfo(params);
        this.isConflict = res && res.result.clash || false;
      } catch (error) {
        console.error('checkCalendarClash error', error);
      }
    },
    // 计划时间修改
    modifyPlanTimeHandle(type){
      if(type == 'modifyCalendarPlanTime'){
        this.openDialog('modifyCalendarPlanTime')
      }else{
        this.openDialog('modifyPlanTime')
      }
    },
    nextStep() {
      this.nowGuideStep++;
    },
    stopStep() {
      this.nowGuideStep = this.detailSteps.length + 1;
    },
    /**
     * 折叠
     */
    collapseBtn() {
      this.collapse = !this.collapse;
      console.log(this.$refs.bizProcess)
      // 解决展开时有时会触发内容区域滚动
      if (this.collapse) {
        this.collapsing = true;
        setTimeout(() => {
          this.collapsing = false;
        }, 0)
      }
    },
    /**
     * 滚动的距离
     */
    getScroll(e) {
      if(e.target.scrollTop === 0 && e.target.scrollHeight - e.target.clientHeight > 20 ){
        this.collapse = true
      }else{
        this.collapse = false
      }
    },
    // 是否含有某一指定权限
    hasAuth(keys) {
      return AuthUtil.hasAuth(this.permission, keys);
    },
    jump() {
      window.location.href = `${this.$resourcePrefix}/setting/task/taskSet`
    },
    // 编辑跳转
    goEdit() {
      const id = this.task.id;
      window.location.href = this.editAuth ? `${this.$resourcePrefix}/task/edit/${id}` : `${this.$resourcePrefix}/task/noFilterEdit/${id}`;
    },
    // 复制工单
    goCopyTask() {
      window.location.href = `${this.$resourcePrefix}/task/copyTask?taskId=${this.task.id}`;
    },
    // 删除工单
    async deleteTask() {
      this.pending = true;

      try {


      
        let warningMsg = i18n.t('task.tip.deleteTaskTip1');

        if (this.task?.projectTaskId) {
          // 工单类型的任务删除弹窗提示
          warningMsg = i18n.t('common.projectManage.deleteTip1');
        }
        if(this.isArchive){
          const result = await this.$platform.confirm(warningMsg);
          if (!result) return this.pending = false;
          const {code, message} = await ArchiveApi.removeTask({taskIds:[this.task.id]});
          this.$notify({
            title: code === 0 ? i18n.t('common.base.deleteSuccess') : i18n.t('common.base.deleteFail'),
            message,
            type: code === 0 ? 'success' : 'error'
          });
          if(code === 0){
            this.closeAndRefreshFromTab()
          }
          return
        }

        /**
        * 如果工单为未完成状态，则需要判断工单是否曾回退，而且在最后一次完成时是否使用了备件
        * 如果使用了备件，需要提示
        */
        if (this.unFinishedState) {
          const res = await TaskApi.finishedWithPart({ taskId: this.task.id });
          if (!res.success) {
            warningMsg = i18n.t('task.tip.deleteTaskTip2');
          } else if (res.success && res.result) {
            warningMsg = i18n.t('task.tip.deleteTaskTip3');
          }
        }

        const result = await this.$platform.confirm(warningMsg);
        if (!result) return this.pending = false;

        TaskApi.deleteTask([this.task.id]).then(res => {
          if (res.success) {
            this.closeAndRefreshFromTab();
          } else {
            this.$platform.alert(res.message);
            this.pending = false;
          }
        }).catch(err => {
          this.pending = false;
        })

      } catch (e) {
        console.error('deleteTask error', e);
      }
    },
    // 出发
    async setOut() {
      const warningMsg = i18n.t('task.tip.setOutTip');
      const result = await this.$platform.confirm(warningMsg);
      if (!result) return;
    },
    // 回退工单
    async backTask() {
      try {
        // 判断工单上备件来源和当前租户备件库配置是否相同
        let res = await TaskApi.getReceiptSparePartProperty({ taskId: this.task.id });
        if (!res.result) return this.openDialog('back');

        if (!await this.$platform.confirm(i18n.t('task.tip.backTaskDialogTip3'))) return;

        this.openDialog('back');
      } catch (e) {
        console.error('backTask error', e);
      }
    },
    // 回退工单
    back() {

      const {checkBack, isReasonRequired} = this
      if (!checkBack && isReasonRequired) {
        this.$platform.alert(i18n.t('task.detail.pleaseChooseBackReason'));
        return
      }

      // At
      let receivers = ''
      let query = ''
      let reason = this.backDialog.reason
      if(reason){
        reason = enCodeAtText(this.backDialog.reason, this.atUsers);
        receivers = getReceivers(this.backDialog.reason, this.atUsers)
        let queryData = {
          receivers,
          tenantId: useTenantId().value,
          content: cutAtTextContent(this.backDialog.reason),
          sendUserName: useRootUser().value?.displayName,
          bizId: this.task.id,
          bizNo: this.task.taskNo,
        };
        query = '?';
        for (let i in queryData) {
          query += `&${i}=${queryData[i]}`;
        }
      }

      reason = reason.trim();
      // if (!reason) return this.$platform.alert('请填写回退说明');

      this.pending = true;

      // 判断是完成回退还是结算回退
      const API = this.task.state == 'finished' ? 'rollBackTask' : 'rollBackBalance';

      const params = { taskId: this.task.id, reason, customReason: checkBack };
      TaskApi[API](params, query).then(res => {
        if (res.success) {
          let fromId = window.frameElement.getAttribute('fromid');
          // this.$platform.refreshTab(fromId);

          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      })
    },
    inputBackContent(event){
      let value = event.target.value;
      this.backDialog.reason = value;
    },
    // 取消
    cancelModel(item) {
      if (item.needVipApprove) {
        this.proposeApprove(item);
      } else {
        const {data, customReason} = item
        this.proposeApprove(data, {customReason});
      }
    },
    // 暂停工单
    async pause() {
      if (this.pending) return;

      const {checkBack, isReasonRequired} = this
      if (!checkBack && isReasonRequired) {
        this.$platform.alert(i18n.t('task.detail.pleaseChoosePauseReason'));
        return
      }

      this.pending = true;
      let { reason } = this.pauseDialog;
      let taskId = this.task.id;

      let receivers = ''
      let query = ''
      let remark = reason
      if(reason){
        remark = enCodeAtText(reason, this.atUsers);
        receivers = getReceivers(reason, this.atUsers)
        let queryData = {
          receivers,
          tenantId: useTenantId().value,
          content: cutAtTextContent(reason),
          sendUserName: useRootUser().value?.displayName,
          bizId: this.task.id,
          bizNo: this.task.taskNo,
        };
        query = '?';
        for (let i in queryData) {
          query += `&${i}=${queryData[i]}`;
        }
      }

      // 先判断是否需要高级审批
      let approveParams = {
        taskId: taskId,
        action: 'pause',
        pauseInfo: {
          taskId,
          reason,
          customReason: checkBack,
        }
      }

      const approveResult = await TaskApi.checkNeedVipApprove(approveParams);
      if (approveResult.success && approveResult.result.needVipApprove) {
        this.pauseDialog.visible = false;
        this.atUsers = []
        this.proposeApprove(approveResult.result);
        this.pending = false;
        return
      }


      // 暂停是否需要审批
      const result = await TaskApi.pauseApproveCheck({ id: taskId, reason });
      // TODO 需要审批判断改成errorCode
      if (!result.succ && Number(result.errorCode) == 10003) {
        this.pauseDialog.visible = false;
        this.atUsers = []
        this.proposeApprove(result.data, {customReason: checkBack});
        this.pending = false;
        return;
      }

      TaskApi.pauseTask({ taskId, reason:remark, customReason: checkBack }, query).then(res => {
        if (res.success) {
          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      })
    },

    inputPauseContent(event){
      let value = event.target.value;
      this.pauseDialog.reason = value;
    },
    // 继续
    unpause() {
      this.pending = true;

      TaskApi.unpauseTask({ taskId: this.task.id }).then(res => {
        if (res.success) {
          this.refreshFromTab();
          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      })
    },
    // 拒绝工单
    async refuse() {

      const {checkBack, isReasonRequired} = this
      if (!checkBack && isReasonRequired) {
        this.$platform.alert(i18n.t('task.detail.pleaseChooseRefuseReason'));
        return
      }

      let reason = this.refuseDialog.reason.trim();
      // if (!reason) return this.$platform.alert('请填写拒绝原因');

      if (!await this.$platform.confirm(i18n.t('task.tip.refuseTaskTip'))) return;

      this.pending = true;

      const params = { taskId: this.task.id, reason, customReason: checkBack };
      TaskApi.refuseTask(params).then(res => {
        if (res.success) {
          this.closeAndRefreshFromTab();
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      })
    },
    // 开始
    async start(params = {}, cal) {
      if (this.pending) return;
      this.pending = true;

      // 开始节点是否配置有表单字段
      const paramsKeysEnable = params && Object.keys(params)?.length > 0

      // 先判断是否需要高级审批
      let approveParams = {
        taskId: this.task.id,
        action: 'start'
      }

      paramsKeysEnable && (approveParams.nodeFormData = {...params?.formData})
      const approveResult = await TaskApi.checkNeedVipApprove(approveParams);
      if (approveResult?.success && approveResult?.result?.needVipApprove) {
        this.proposeApprove(approveResult?.result ?? {});
        this.pending = false;
        paramsKeysEnable && cal()
        return
      }

      // 开始是否需要审批
      let paramsApproval = { }
      paramsKeysEnable && (paramsApproval = params?.formData ?? {})
      const result = await TaskApi.startApproveCheck(this.task.id, paramsApproval);

      if(!result.succ && result.errorCode == 10002) {
        this.$platform.alert(i18n.t('task.tip.startTaskTip1'));
        this.pending = false;
        paramsKeysEnable && cal()
        return
      }

      if(!result.succ && result.errorCode == 10005) {
        this.$platform.alert(i18n.t('task.tip.startTaskTip2'));
        this.pending = false;
        paramsKeysEnable && cal()
        return
      }

      // TODO 需要审批判断改成errorCode
      if (!result.succ && Number(result.errorCode) == 10003) {
        this.proposeApprove(result.data);
        this.pending = false;
        paramsKeysEnable && cal()
        return;
      }

      TaskApi.startTask({ taskId: this.task.id, ...params }).then(res => {
        if (res.success) {
          let fromId = window.frameElement.getAttribute('fromid');
          // this.$platform.refreshTab(fromId);

          if(paramsKeysEnable) {
            cal()
          }
          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      }).finally(() => {
        paramsKeysEnable && cal()
      })
    },
    // 指派工单
    allot() {

      // 新工单新指派
      if (this.isRestructAllot) {
        this.checkNotNullForCard('allot', () => {
          // this.refreshFromTab();
          this.$refs.TaskAllotModal.outsideShow();
        })
      } else {
        this.pending = true;
        location.href = `${this.$resourcePrefix}/task/allotTask?id=${this.task.id}`;
      }
    },
    // 转派工单
    redeploy() {
      // 新工单新转派
      if (this.isRestructAllot) {
        this.obtainReasonByTaskStatus(0)
        this.$refs.TaskAllotModal.outsideShow()
      } else {
        this.pending = true;
        location.href = `${this.$resourcePrefix}/task/redeploy?id=${this.task.id}`;
      }
    },
    // 打印工单
    printTask() {
      this.pending = true;
      TaskApi.printTask({ taskId: this.task.id }).then(res => {
        if (res.status == 0) {
          let url = `${window.location.origin}/print/printTaskDispatcher?token=${res.data}`;
          parent.openHelp(url);

          this.$eventBus.$emit(TaskEventNameMappingEnum.UpdateRecord);
        }
      })
        .catch(err => console.error(err))
        .finally(() => {
          this.pending = false;
        })
    },
    // 分享工单
    shareTask(){
      navigator.clipboard.writeText(window.location.href).then(() => {
        this.$message.success(this.$t('task.setting.taskSetting.copySuccess'));
      })
    },
    // 生成服务报告
    createReport() {
      // 需要判断是否需要用户签字
      if(this.srPrintAuthority.isNeedCustomerSign) {
        // 需要用户签字，打开生成服务报告的弹窗
        this.$refs.serviceReportRef.openDialog()
      } else {
        // 无需用户签字 下载
        this.downloadReport(true)
      }
    },
    // 生成服务报告(已完成状态)
    createServiceReport(item) {
      const { needSign, templateType } = item

      // 不需要签名 && 个人模版
      if (!needSign && templateType !== 1) return

      // 需要用户签字，打开生成服务报告的弹窗
      if (needSign) return this.$refs.serviceReportRef.openDialog(item)
      
      // 无需用户签字 下载
      this.downloadServiceReport(item, true)
    },
    // 下载服务报告(已完成状态)
    async downloadServiceReport(item, isPdf) {
      const fileType = isPdf ? 'pdf' : 'excel'
      location.href = `/task/createServiceReportDownload?taskId=${this.task.id}&taskTypeId=${this.task.templateId}&taskStatus=${item.taskStatus}&fileType=${fileType}&shbLanguage=${i18n.locale}`;
    },
    // 获取服务报告名称
    getServiceReportName(item) {
      // 已命名
      if (item.foreignName) return item.foreignName
      let stateText = TaskStateEnum.getName(item.taskStatus)

      // 自定义的名称
      if(!stateText) {
        stateText = this.taskALlNode?.find(node => node.id === item.taskStatus)?.data?.nodeStateName ?? ''
      }
      return `${stateText}_${this.$t('task.serviceReport')}`
    },
    // 下载服务报告
    async downloadReport(isPdf) {
      const fileType = isPdf ? 'pdf' : 'excel'
      location.href = `/task/createServiceReportDownload?taskId=${this.task.id}&taskTypeId=${this.task.templateId}&taskStatus=${this.processCurrentState}&fileType=${fileType}&shbLanguage=${i18n.locale}`;
    },
    // 撤回审批
    async offApprove() {
      const result = await this.$platform.confirm(i18n.t('task.tip.offApproveTip'));
      if (!result) return;

      this.pending = true;
      TaskApi.offApprove({ apprId: this.unFinishedAppr.id }).then(res => {
        if (res.status == 0) {
          this.refreshFromTab();

          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      })
    },
    // DING
    ding(all = true) {
      let { id, taskNo, executor, synergies } = this.task;

      let users = [];
      users.push(executor.staffId);

      // 所有人(工单负责人和协同人)
      if (all && synergies && synergies.length) {
        synergies.forEach(item => users.push(item.staffId));
      }

      // 使用getRootWindow获取
      const rootWindow = getRootWindow(window);
      rootWindow.send_link_ding_message(users, taskNo, id);
    },
    goNextStep(action) {
      TaskApi[action]({taskId:this.task.id}).then(res => {
        if (res.success) {
          window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
        } else {
          this.$platform.alert(res.message);
          this.pending = false;
        }
      }).catch(err => {
        this.pending = false;
      })
    },
    // 打开弹窗
    async openDialog(action, vipBtnType) {
      this.atUsers = []
      this.checkBack = '' // 清除拒绝原因
      if (action === 'cancel') {
        this.$refs.cancelTaskDialog.openDialog();
        this.obtainReasonByTaskStatus(1)
      } else if (action === 'acceptFromPool' || action === 'accept') {
        // 校验附加组件必填
        this.checkNotNullForCard('accept', () => {
          if(this.isCalendar){
            this.$refs.calendarPlanTimeDialog.beforeOpenForAccept(action);
          }else{
            this.$refs.planTimeDialog.beforeOpenForAccept(action);
          }
        })
      } else if (action === 'modifyPlanTime') {
        this.$refs.planTimeDialog.openDialog(action);
      } else if ( action === 'modifyCalendarPlanTime' || action === 'modifyPlanStartTime' || action === 'modifyPlanEndTime') {
        this.$refs.calendarPlanTimeDialogComponent.openDialog('modifyPlanTime');
      } else if (action === 'approve') {
        // this.openSignatures(vipBtnType)
        this.$refs.approveTaskDialog.openDialog(vipBtnType);
      } else if (action === 'pause') {
        this.pauseDialog.reason = '';
        this.pauseDialog.visible = true;
        this.obtainReasonByTaskStatus(3)
      } else if (action === 'refuse') {
        this.refuseDialog.reason = '';
        this.refuseDialog.visible = true;
        this.obtainReasonByTaskStatus(2)
      } else if (action === 'setOut') { // 出发
        this.setOut();
      } else if (action === 'back') {
        this.$track.clickStat(this.$track.formatParams('ROLLBACK'));

        this.backDialog.reason = '';
        this.backDialog.visible = true;
        this.obtainReasonByTaskStatus(4)
      } else if (action === 'finish') {

        if (this.task?.projectTaskId) {
          // 工单类型的任务，先校验前置任务是否完成
          await this.checkPreTask(() => {
            this.taskReceiptDia()
          })
        } else {
          this.taskReceiptDia()
        }
      } else if (action === 'editReceipt') {
        this.$refs.taskReceiptEdit.openDialog('edit');

      } else if (action === 'balance') {
        this.checkNotNullForCard('cost', () => {
          this.rightActiveTab = 'balance-tab';
          this.$nextTick(() => {
            this.$refs.taskAccount.openDialog('create');
          })
        })
      } else if (action === 'feedback') {
        this.rightActiveTab = 'feedback-tab';
        this.$nextTick(() => {
          this.$refs.taskFeedback.feedback();
        })
      } else if (action === 'timeAxis') {
        this.$track.clickStat(this.$track.formatParams('CHECK_ALL_TIME_AXIS'));
        this.$nextTick(() => {
          this.$refs.timeAxis.openDialog();
        })
      } else if (action === 'adjustTime') {
        this.$refs.calendarPlanTimeDialog.openDialog(action);
      } else if( action === 'settlement') {
        this.rightActiveTab = 'settlement';
      }

    },
    openAdvance(btnType) {
      
    },

    openSignatures(btnType,name) {
      
      this.btnType = name
      if (this.pending) return;
      this.pending = true;

      this.approve = {};
      TaskApi.getApprove({ id: this.unFinishedAppr.id })
        .then((res) => {
          if (res.status == 0) {
            console.log(2050,res)
            if (res.data?.processorInstanceId) {
              this.fromVip = true
              this.approve = res.data;
              // this.otherInfo = this.approve?.otherInfo?.params ?? {};
              this.getVipData(name)
            } else {
              // this.visible = true;
              this.approve = res.data;
              // this.otherInfo = this.approve.otherInfo.params;
              this.currLevel = res.data.approverLevel;
            }
          } else {
            this.$platform.alert(res.message);
          }
        })
        .catch((err) => console.log(err))
        .finally(() => {
          this.pending = false;
          console.log(this.approve,this.fromVip,9999)
          if(name) this.$refs.taskAdvancedApprove.open(btnType);
          else this.$refs.approveSignature.openDialog(btnType)
        })
    },

    async getVipData(btnType) {
      let res = {}
      res = await TaskApi.getApproveLoad({approveId: this.unFinishedAppr.id, nodeTaskBizId: this.customNodeId})
      if (res.success) {
        const { approveInfo, attribute } = res.result || {}
        this.approveInfoParams = approveInfo || []
        this.vipJson = JSON.parse(attribute)
        if (this.vipJson?.cells) {
          const { buttons } = approveInfo || []

          this.vipBtnSetting = ((buttons || []).filter((item) => item.enName === btnType))[0] || {}
        }
      }
    },

    taskReceiptDia() {
      this.checkNotNullForCard('finish', () => {
        this.$refs.taskReceiptEdit.openDialog()
        window.localStorage.removeItem('materialTableData')
      })
    },

    checkPreTask(callback) {
      this.pending = true;
      checkPreTaskIsComplete({id: this.task.projectTaskId})
      .then((res) => {
          this.pending = false;
          const { success, data, message  } = res
          if (!success) return this.$message.error(message)
          if (data?.flag) {
            callback()
          } else {
            this.$message.error(data?.msg)
          }
        })
        .catch(err => {
          this.pending = false;
        })
    },

    /**
     *
     * @description 获取工单异常原因
     */
    async obtainReasonByTaskStatus(taskType) {
      const {success, result} = await TaskApi.obtainReasonByTaskStatus(taskType)
      if (success) {
        const {systemAdmin, reason, notNull} = result
        this.systemAdmin = systemAdmin
        this.backList = reason
        this.notNull = notNull
      }
    },
    // 发起审批
    proposeApprove(data, customReason = '') {
      this.$refs.proposeApprove.openDialog(data, customReason);
    },
    changeTaskProcessState(state) {
      this.taskState = state;
    },
    /**
    * @description 获取客户关联的工单数量
    */
    getCountForCreate() {
      const params = { module: 'customer', id: this.customer.id };
      TaskApi.getCountForCreate(params).then((result = {}) => {

        result.all += this.archiveCount;
        this.customerRelationTaskCountData = result;
      })
    },
    /**
    * @description 打开客户详情
    */
    openCustomerView(openTaskTab) {
      if (!this.allowOpenCustomerView) return;

      let fromId = window.frameElement.getAttribute('id');
      const customerId = this.customer.id;

      if(!customerId) return;

      let params = 'noHistory=1';

      if (openTaskTab) params += '&active=task';

      Platform.openAccurateTab({
        type: PageRoutesTypeEnum.PageCustomerView,
        key: customerId,
        params,
        fromId
      })
    },
    /**
    * @description 拨打电话
    */
    async makePhoneCall() {
      // 未开通呼叫中心
      if (!this.showCallPhone) return;
      let phone = this.task.tlmPhone || this.customer.lmPhone;
      if (!phone) return;

      ctiCallOut(phone) // taskType:'task'
    },
    /**
    * @description 打开地图
    */
    openMap() {
      let address = this.task.taddress;

      let markerDom = this.buildMapMarkerContent();
      let infoDom = this.buildMapInfoContent();

      this.$fast.map
        .display({ ...address }, {}, markerDom, infoDom)
        .catch(err => console.error('openMap catch an err: ', err));
    },
    buildMapMarkerContent() {
      return `<i class="bm-location-dot"></i><div class="map-address-title">${i18n.t('common.base.locationMap.customerAddress')}</div>`;
    },
    buildMapInfoContent() {
      return `
        <div class="map-info-window-content">
          <div class="customer-name">${ this.customer.name }</div>
          <p><label>${i18n.t('common.base.contact')}：</label>${ this.lmName }</p>
          <p><label>${i18n.t('common.base.phone')}：</label>${ this.lmPhone }</p>
          <p><label>${i18n.t('common.base.locationMap.address')}：</label>${ this.address }</p>
        </div>
      `;
    },
    /**
    * @description 是否加密字段
    */
    isEncryptField(value) {
      return value === ENCRYPT_FIELD_VALUE;
    },
    buildButtonData() {
      let buttonData = [
        { name: this.customNode.nodeBtnName,
          type: 'primary',
          isCustomBtn: true,
          show: this.isCanCustomNode, event: () => { this.checkNotNullForCard(this.currentNodeId, this.openCustomNode)}
        },
        { name: i18n.t('common.task.button.allot'), type: 'primary', show: this.allowAllotTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('TASK_ALLOT'));
          this.allot();
        } },
        { name: i18n.t('common.task.button.acceptFromPool'), type: 'primary', show: this.allowPoolTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('ACCEPT_TASK_FROM_POOL'));
          this.openDialog('acceptFromPool');
        } },
        { name: i18n.t('common.task.button.accept'), type: 'primary', show: this.allowAcceptTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('ACCEPT_TASK'));
          this.openDialog('accept');
        } },
        { name: i18n.t('common.task.button.start'), type: 'primary', show: this.allowStartTask && !this.showSetOutButton, event: () => {
          if(this.haveFaceCheckGray && this.haveFaceStartCheck){
            return this.$platform.alert( this.userHaveFaceInfo ? t('task.face.tips2') : t('task.face.tips1'))
          }
          this.$track.clickStat(this.getBtnsTrackData('START_TASK'));
          this.checkNotNullForCard('start', this.beforeStart);
        } },
        // 出发打卡
        { name: i18n.t('common.task.button.setOut'), type: 'primary', show: this.showSetOutButton, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('SETOUT_TASK'));
          this.openDialog('setOut');
        } },
        { name: i18n.t('common.task.button.finish'), type: 'primary', show: this.allowFinishTask, event: () => {
          if(this.haveFaceCheckGray && this.haveFaceFinishCheck){
            return this.$platform.alert( this.userHaveFaceInfo ? t('task.face.tips4') : t('task.face.tips3'))
          }
          this.$track.clickStat(this.getBtnsTrackData('FINISH_TASK'));
          this.openDialog('finish');
        } },
        { name: i18n.t('common.task.button.back'), type: 'primary', show: this.allowBackTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('ROLLBACK_TASK'));
          this.backTask();
        } },
        { name: i18n.t('common.task.button.balance'), type: 'primary', show: this.viewBalanceTab && this.allowBalanceTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('BALANCE_TASK'));
          this.openDialog('balance');
        } },
        { name: i18n.t('common.task.button.review'), type: 'primary', show: this.viewFeedbackTab && this.allowReviewTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('FEEDBACK_TASK'));
          this.openDialog('feedback');
        }, btnType: 'review' },
        { name: i18n.t('common.task.button.refuse'), type: 'danger', show: this.allowRefuseTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('REFUSE_TASK'));
          this.openDialog('refuse');
        } },
        // 附加组件-多个
        { name: this.$t('event.setting.serviceEventTypeSetting.flow.component.title1'),
          type: 'plain-third',
          isAddons: true,
          show: this.showMoreAddonsBtn
        },
        // 附加组件-单个
        { name: this.sigleAddon.btnName,
          type: 'plain-third',
          show: this.showOneAddonsBtn, event: () => {this.openAddonsDialogAuto({data: this.sigleAddon.cardId})}
        },
        { name: i18n.t('common.task.button.pause'), type: 'plain-third', show: this.allowPauseTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('PAUSE_TASK'));
          this.openDialog('pause');
        } },
        { name: i18n.t('common.task.button.continue'), type: 'primary', show: this.allowGoOnTask, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('CONTINUE_TASK'));
          this.unpause();
        } },
        // { name: i18n.t('common.task.button.approve'), type: 'primary', show: this.allowApprove, event: () => {
        //   this.$track.clickStat(this.getBtnsTrackData('APPROVE_TASK'));
        //   this.openDialog('approve');
        // } },
        { name: i18n.t('common.task.button.approve'), type: 'primary', show: this.allowQualityApprove, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('APPROVE_TASK'));
          this.openDialog('approve');
        } },
        { name: i18n.t('common.task.button.offApprove'), type: 'default', show: this.allowoffApprove, event: () => {
          this.$track.clickStat(this.getBtnsTrackData('WITHDRAW_APPROVE_TASK'));
          this.offApprove();
        } }
      ]

      if (this.vipApproveSetting?.buttons && this.vipApproveSetting?.buttons.length > 0) {
        this.vipApproveSetting.buttons.forEach((item) =>{
          buttonData.push({
              name: this.setNameLanguage(item.nameLanguage),type: 'primary', show: this.allowVipApprove, event: () => {
              this.$track.clickStat(this.getBtnsTrackData('APPROVE_TASK'));
              this.openDialog('approve', item.enName);
            }, enName: item.enName,
          })
        })
        console.log(this.vipApproveSetting, 'this.vipApproveSetting')
      } else {
        buttonData.push(
          { name: i18n.t('common.task.button.approve'), type: 'primary', show: this.allowApprove, event: () => {
            this.$track.clickStat(this.getBtnsTrackData('APPROVE_TASK'));
            this.openDialog('approve');
          }, btnType: 'approve' },
        )
      }

      // 如果高级审批有的话 展示同意/拒绝按钮

      return buttonData.reverse();
    },

    setNameLanguage(nameLanguage) {
      let laEnv = this.$i18n.locale ;
      return nameLanguage[laEnv]
    },
    /**
     * 关闭并刷新from Tab
    */
    closeAndRefreshFromTab() {
      this.refreshFromTab()
      let id = window.frameElement.dataset.id
      setTimeout(()=>{
        this.$platform.closeTab(id)
      }, 600)
    },
    outsideUpdateTask(task = {}) {
      this.task = task
    },
    outsideUpdateRecords() {
      this.$eventBus.$emit(TaskEventNameMappingEnum.UpdateRecord);
    },
    // 检验附加组件是否必填
    checkNotNullForCard(flow, callback) {
      this.pending = true;
      TaskApi.checkNotNullForCard({ id: this.task.id, flow })
        .then(res => {
          this.pending = false;

          if (res.status == 0) {
            callback();
          } else {
            if(res.data) {
              this.openAddonsDialogAuto(res)
            }else {
              this.$platform.alert(res.message);
            }
          }
        })
        .catch(err => {
          this.pending = false;
        })
    },
    onApproveSuccessHandler() {
      window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`
    },
    getQualityByTaskId() {
      TaskApi.getQualityByTaskId({ taskId: this.task.id }).then(res => {
        this.task.qualityInfo = res.result
      }).catch(err => {})
    },
    // 获取生成服务报告按钮展示规则
    async srCheckPrintAuthority() {
      // 查询服务报告按钮显示规则，如果是当前状态是自定义节点状态taskStatus 取节点id
      const params = {
        taskTypeId: this.task.templateId || '',
        taskStatus: this.processCurrentState
      }
      const { success, data } = await TaskApi.serviceReportCheckPrintAuthority(params)
      this.srPrintAuthority = success ? data : {}

      if (this.finishedState && this.srPrintAuthority?.isFinishNodeShowAllServiceReport) {
        this.getServiceReportList()
      }
    },
    // 获取服务报告模板列表
    async getServiceReportList() {
      try {
        const result = await SettingTaskApi.getServiceReportListByTaskType({ taskTypeId: this.task.templateId })
        this.serviceReportList = result?.data || []
      } catch(err) {
        console.error('task-detail-view getServiceReportList error: ', err)
      }
    },
    async refreshPage() {
      try {
        this.$emit('changeLoading', true);
        // 刷新动态信息服务商结算信息
        /* await this.updateInfoRecord();*/ // 暂时不刷新动态信息，等产品确认怎么做
        // 服务商结算信息
        await this.$refs.provideSettle.initializeSettle();
      } catch (error) {
        console.error('refresh page error', error);
      } finally {
        this.$emit('changeLoading', false);
      }
    },
    async initRightTabBar(){
      if (this.taskLayout === 1) {
        this.tabPosition = 'left';
      }
      let { 
        TabBarListItemKey: tabName, 
        TabBarListItemLabel: tabLabel, 
        TabBarListItemShow: tabShow, 
        TabBarCardInfoType: tabIsCardType, 
        TabCardInfoSingle: tabIsCardSingle, 
        TabBarListItemType:tabType, 
        TabCardCardId, 
        TabCardCardType,
      } = BaseTabBarUsualEnum;

      this.rightTabBarLoading = true;
      let addCardData = []
      // 附加组件展示的tab
      try {
        addCardData = this.taskCards.map(card => {
          const { cardNameLanguage, cardName } = card;
          if(cardName === '故障清单') {
            return {
              [tabLabel]: cardNameLanguage?.[this.$i18n.locale] || cardName,
              [tabName]: 'fault-tab',
              [tabShow]:true,
              [tabType]:tabIsCardType,
              [TabCardCardId]: card.cardId,
            }
          }
          return {
            [tabLabel]: cardNameLanguage?.[this.$i18n.locale] || cardName,
            [tabName]: `${tabIsCardSingle}${card.cardId}`,
            [tabShow]:true,
            [tabType]:tabIsCardType,
            [TabCardCardId]: card.cardId,
            [TabCardCardType]: card.inputType,
          }
        })
      } catch (error) {
        console.warn(error, 'error try catch taskCards');
      }

      // 服务商结算灰度，开启时展示新的结算。没有开启展示旧的结算 this.providerSettleV2 && this.provideSettleConfig && this.provideSettleConfig.taskSettleTableVisible
      let barArr = [
        {[tabName]:'record', disabled:true, [tabLabel]:i18n.t('task.detail.dynamicInfo'), [tabShow]:true},
        // 任务信息页面
        ...(this.viewReceiptTab ? [{[tabName]:'receipt-view', [tabLabel]:i18n.t('task.receiptInfo'), [tabShow]:true }] : []),
        ...(!this.providerSettleV2 && this.provideSettleConfig && this.provideSettleConfig.tabVisible ? [{[tabName]:'settlement', [tabLabel]:i18n.t('task.providerSettle'), [tabShow]:true }] : []),
        ...(this.viewBalanceTab ? [{[tabName]:'balance-tab', disabled:true, [tabLabel]:i18n.t('task.auditSettle'), [tabShow]:true }] : []),
        ...(this.viewFeedbackTab ? [{[tabName]:'feedback-tab', [tabLabel]:i18n.t('task.customerEvaluation'), [tabShow]:true }] : []),
        ...(this.providerSettleV2 && this.provideSettleConfig && this.provideSettleConfig.taskSettleTableVisible ? [{[tabName]:'settlement-tab', [tabLabel]:i18n.t('task.providerSettle'), [tabShow]:true }] : []),
        ...(this.viewTaskCardTab ? addCardData : []),
        ...(this.viewTaskMaterialTab ? [{[tabName]:'material-tab', [tabLabel]:i18n.t('task.detail.materialList'), [tabShow]:true}] : []),
      ]

      // 如果有任务id就展示tab
      if (this.task?.projectTaskId) {
        barArr.unshift({
          tabName: 'pro-task-tab',
          disabled: true,
          tabLabel: i18n.t('common.projectManage.detail.taskDetail.title'),
          tabShow: true,
        })
      }
      
      barArr.forEach(tab => {
        tab.needTrack = true
        tab.position = 'right'
      })
      let parasm_ = {
        equipment:StorageHttpParamsForTerminalType.PC,
        bizType:StorageHttpParamsForModuleType.Task,
        bizTypeId:this.task.templateId
      }
      try {
        // 获取tabbar用户行为缓存/*  */
        let storageList = await getStorageForDetailTabbar(parasm_);
        if(storageList.status !== 0) {
          throw storageList.message
        }
        let storageList_ = storageList.data.map(item=>{
          const { cardId, checked} = item;
          return {
            [tabName]:cardId,
            [tabShow]:checked
          }
        })
        barArr = computedTabList(barArr, storageList_)
      } catch (error) {
        console.warn(error, 'error try catch getStorageForDetailTabbar');
      }



      this.$nextTick(()=>{
        let firstItem = barArr && barArr.find(item=>item[tabShow])
        this.rightActiveTab = firstItem?.[tabName];
        this.rightActiveTabItem = firstItem;
        this.rightTabBarLoading = false;
      })
      this.tabBarList = barArr;
      this.taskLayoutTabBarList = cloneDeep(barArr.filter(item => item.tabShow));
      if(this.taskLayoutTabBarList.findIndex(item => item.tabName === 'task-view') === -1) {
        this.taskLayoutTabBarList.unshift(...this.taskLeftBarList)
      }
    },
    // 校验多次附加组件数据是否有改动
    checkMultipleCardDataChange(previous, next) {
      return this.$refs.taskDetailCard.checkMultipleCardDataChange(previous, next);
    },
    tabBarChangeItem(item){
      // 校验多次附加组件数据是否有改动且 未保存
      const currentTabIndex = this.tabBarList.findIndex(card => card.tabName === this.rightActiveTab); // currentTabIndex 是要离开的tab
      if(this.isShowCardMultiSave && this.tabBarList[currentTabIndex].inputType === BaseTabBarCardTypeEnum.Multiple) {
        return this.checkMultipleCardDataChange(this.tabBarList[currentTabIndex], item);
      }

      this.tabBarChangeItemNext(item);
    },
    tabBarChangeItemNext(item) {
      let { TabBarListItemKey: tabName, TabBarListItemType: tabType, TabBarCardInfoType } = BaseTabBarUsualEnum;
      this.$refs.rightContent?.scrollTo(0, 0)
      this.tabPosition = item.position;
      if(this.taskLayout === 1 || item.position === 'left') {
        this.leftActiveTab = item[tabName];
      } 
      if(item.position === 'right') {
        this.rightActiveTab = item[tabName];
        this.rightActiveTabItem = item;
      } 
      this.$nextTick(() => {
        this.$refs.TaskDetailMainElement.scrollTop = 0;
      })

    },
    /**
     * @des tabbar数据发生变更钩子函数
     */
    tabBarUpdateList(list){
      const { TabBarCardInfoType, TabBarListItemKey:tabName, TabBarListItemShow:tabShow } = BaseTabBarUsualEnum;
      let list_ = list.map(item=>{
        return {
          cardId: item.type == TabBarCardInfoType ? item.id : item[tabName],
          checked: item[tabShow]
        }
      })
      let parasm_ = {
        equipment:StorageHttpParamsForTerminalType.PC,
        bizType:StorageHttpParamsForModuleType.Task,
        bizTypeId:this.task.templateId,
        cardList:list_
      }
      setStorageForDetailTabbar(parasm_)
      this.taskLayoutTabBarList = cloneDeep(this.tabBarList.filter(item => item.tabShow));
    },
    getBtnsTrackData(id, data) {
      return this.$track.formatParams(id, data, 'DETAIL_BTNS_GROUP')
    },
    async initGuide() {
      const RootWindow = getRootWindow(window);
      if (!RootWindow?.grayAuth?.CHAT_IM || !this.isShowIm) return;

      try {
        let userGuideStroage = await getUserGuideStorageBase();
        if (!Object.keys(userGuideStroage).includes(PULL_GROUP_GUIDE)) {
          setTimeout(() => {
            this.pullGroupGuide(userGuideStroage);
          }, 1000);
        }
      } catch (error) {
        console.error('initGuide error', error);
      }
    },
    pullGroupGuide(userGuideStroage) {
      let id = 'pull-group-guide';
      let lastFinish = 1;

      this.$Guide([
        {
          content: this.$t('common.guide.task.view.content1'),
          haveStep: true,
          direction: 'row',
          nowStep: 1,
          id,
          domObj: () => {
            return document.querySelector('.icon-a-teambeifen2');
          },
          needCover: true,
          lastFinish,
          show: true,
        },
        {
          content: this.$t('common.guide.task.view.content2'),
          haveStep: true,
          nowStep: 2,
          id,
          domObj: () => {
            return document.querySelector('.base-select-user-footer > .el-button--primary');
          },
          diyClass:'im-guide-with-select-user',
          needCover: true,
          finishBtn: this.$t('common.base.finish'),
          show: true,
        },
      ], 0, '', (e) => {
        const { type, nowStep } = e;
        if (type === 'next' && nowStep == 0) {
          this.createGroudChat();
        }
        return new Promise((resolve, reject) => {
          resolve();
        })
      })
        .create()
        .then(res_ => {
          if (res_) {
            setUserGuideStorageBase({
              userGuideList: [
                {
                  type: PULL_GROUP_GUIDE,
                  step: 1,
                  isComplete: 1
                }
              ]
            }, userGuideStroage).then(res=>{
              userGuideStroage = res;
            });
          }
        });
    },


    // 初始化获取审批按钮展示
    async initApproveBtn() {
      await TaskApi.getApproveLoad({approveId: this.unFinishedAppr.id, nodeTaskBizId: this.customNodeId}).then((res) => {
        if (res.success) {
          this.vipApproveSetting = res.result?.approveInfo ?? {}
        }
      })
    },

    async initFormBuilderCellCount(){
      const { getSystemViewLayout } = useStateSystemViewLayout()
      const count = await getSystemViewLayout()
      this.baseLayout = count.baseLayout || 2;
      this.formCellCount = count.formCellCount || 1;
    },

    // 翻译地址
    async addressSwitch(){
      let { taddress } = this.task;
      let key = getCountryKey(taddress)

      this.addressNameObj = await addressKeyToViewLanguage(key,taddress);
    },
    refreshTaskList() {
      try {
        const searchParams = new URLSearchParams(window.location.search);
        const createType = searchParams.get('createType'); 
        if(createType === 'copyTask') {
          setTimeout(() => {
            this.$platform.refreshTab('frame_tab_M_TASK_LIST');
          }, 2000)
        }
      } catch(error) {
        console.error(error)
      }
    },
    // 跳转上一页下一页
    changePage(type = 'next') {
      let pageData;
      try {
        pageData = JSON.parse(sessionStorage.getItem(this.$route.query.JumpKey) || '[]');
      } catch (error) {
        console.log(error);
        return;
      }
    
      const fromId = window.frameElement.getAttribute('id');
      const currentIndex = pageData.findIndex(page => page?.taskId === this.task.id);
    
      if (currentIndex === -1) {
        return;
      }

      const nextIndex = type === 'next' ? currentIndex + 1 : currentIndex - 1;
    
      if (nextIndex < 0 || nextIndex >= pageData.length) {
        this.$message.error(type === 'next' ? this.$t('common.base.tip.noNextPage') : this.$t('common.base.tip.noLastPage'));
        return;
      }
    
      const { taskId = '', taskNo = '' } = pageData[nextIndex];
      this.$platform.closeTab(`task_view_${this.task.id}`);
      Platform.openAccurateTab({
        type: PageRoutesTypeEnum.PageTaskView,
        key: taskId,
        titleKey: taskNo,
        params: `noHistory=1&JumpKey=${this.$route.query.JumpKey}`,
        fromId,
      });
    }
  },
  created() {
    // 折叠面板缓存
    let collapse = sessionStorage.getItem(`task_customer_collapse_${this.task.id}`);
    let collapseDirection = sessionStorage.getItem(`task_collapseDirection_${this.task.id}`);

    this.collapse = JSON.parse(collapse || 'true');
    this.collapseDirection = collapseDirection || '';
    this.refreshTaskList();

    this.getTaskFlowNode();
    this.srCheckPrintAuthority()
    this.getWikiConfig()
    this.getTaskConfig()
    this.getUserCardConfig()
  },
  async mounted() {
    try {
      this.$emit('changeLoading', this.canViewTask);
      this.addressSwitch()
      await this.initFormBuilderCellCount()

      // 如果是高级审批模式
      if (this.initData.unFinishedAppr?.processorInstanceId) {
        await this.initApproveBtn()
      }

      // 一键拉群引导
      this.$nextTick(() => {
        this.initGuide();
      });

      

      let { templateId } = this.task;

      this.getConfig(templateId)

      // 工单详情需要展示富文本字段
      let subtask = [
        TaskApi.getAllFields({ typeId: templateId, tableName: TableNameEnum.Task, isFromSetting: false, isShowRichText:true })
      ];

      if(this.taskFlowExtend) {
        subtask = [TaskApi.getTheFieldOfNodesThatHaveBeenPassed({ taskId: this.task.id })]
      }

      // 显示回执时获取回执字段信息
      if (this.allowFinishTask || this.showReceipt) subtask.push(TaskApi.getAllFields({ typeId: templateId, tableName: TableNameEnum.TaskReceipt, isFromSetting: true, isShowRichText:true }));

      const result = await Promise.all(subtask);

      const fields = this.taskFlowExtend ? (result[0]?.result ?? []) : result[0] || [];
      this.fields = [...fields, {
        displayName: i18n.t('task.systemInfo'),
        fieldName: 'task_system_separator',
        formType: 'separator',
        isSystem: 1,
      },{
        displayName: i18n.t('task.executor'),
        fieldName: 'executor',
        formType: 'user',
        isSystem: 1,
      }, {
        displayName: i18n.t('task.synergies'),
        fieldName: 'synergies',
        isSystem: 1
      }, {
        displayName: i18n.t('common.base.completeTime'),
        fieldName: 'completeTime',
        formType: 'timestamp',
      }, {
        displayName: i18n.t('common.base.degree'),
        fieldName: 'degree'
      }, {
        displayName: i18n.t('task.taskState'),
        fieldName: 'state'
      }, {
        displayName: i18n.t('common.base.createUser'),
        fieldName: 'createUser',
        formType: 'user',
        isSystem: 1,
      }, {
        displayName: i18n.t('common.base.createTime'),
        fieldName: 'createTime',
        formType: 'timestamp',
        isSystem: 1,
      }, {
        displayName: i18n.t('task.allotUser'),
        fieldName: 'allotUser',
        formType: 'user',
        isSystem: 1,
      }, {
        displayName: i18n.t('common.base.createSource'),
        fieldName: 'source',
        formType: 'user',
        isSystem: 1,
      }];

      const {
        complementCustomerRelationFieldsDateType,
        complementProductRelationFieldsDateType,
      } = useComplementRelatedFieldDateType()
      // 检查是否有关联客户字段、补全时间格式信息
      complementCustomerRelationFieldsDateType(this.fields, this.task?.customer?.id)
      // 检查是否有关联产品字段、补全时间格式信息
      complementProductRelationFieldsDateType(this.fields)
      
      // 查询客户关联工单数量
      if (this.canSeeCustomer) {
        this.getCount().then(() => {
          this.getCountForCreate();
        })
      }
      // 开启满意度灰度 则不显示满意度字段 关联bug编号15032
      if(this.satisfaction) {
        this.fields = this.fields.filter(item => item.fieldName !== 'degree')
      }
      let calendarPlanNum = 0;
      let calendarPlanTimeIndex = null;
      let richtextObj_ = {};
      this.fields.forEach(async (field, i) => {
        if(field.formType == 'richtext'){
          // 富文本信息需要从接口获取
          let { isSystem, fieldName } = field;
          let { task : task_ } = this;
          let id = isSystem == 1 ? task_[fieldName] : task_.attribute[fieldName]
          if(id){
            richtextObj_[id] = fieldName;
          }
          // let content_ = await getRichTextContent({
          //   ids:[id]
          // })
          // let richtextCon = '';
          // if(content_.code == 0){
          //   richtextCon = content_.result[0].content;
          // }
          // isSystem == 1 ? this.task[fieldName] = richtextCon : this.task.attribute[fieldName] = richtextCon
        }
        if (field.fieldName == 'attachment') {
          let { isEncryptAttachment, attachment } = this.task

          // 系统附件加密
          if (isEncryptAttachment) {
            this.task.attachment = ENCRYPT_FIELD_VALUE;
          } else {
            this.task.attachment = attachment.filter(item => !item.receipt);
          }
        }
        if(field.formType == 'quality') {
          this.getQualityByTaskId()
        }
        if(field.fieldName == 'planStartTime' || field.fieldName == 'planEndTime'){
          calendarPlanNum++;
          calendarPlanTimeIndex = i;
        }
      })

      let richtextIds = Object.keys(richtextObj_) || [];
      if (richtextIds.length) {
        let content_ = await getRichTextContent({
          ids: richtextIds,
        });
        let richtextCon = '';
        if (content_.code == 0) {
          content_.result?.forEach((item, index) => {
            let key_ = richtextIds[index];
            let fieldName_ = richtextObj_[key_];
            try {
              richtextCon = item.content;
            } catch (error) {
              console.warn(error, 'error try catch');
            }
            this.task.attribute[fieldName_] = richtextCon
          });
        }
      }
      if( calendarPlanNum >= 2 ){

        this.fields.splice(calendarPlanTimeIndex, 0, {
          displayName: i18n.t('common.base.createSource'),
          fieldName: 'calendarPlanTime',
          formType: 'calendarPlanTime',
          isSystem: 1
        })
      }

      // 开始结束时间共存的时候再掉冲突接口
      const timeNum = this.fields.reduce((total, cV)=>{
        if(cV.fieldName === 'planStartTime' || cV.fieldName === 'planEndTime'){
          total++;
        }
        return total;
      }, 0);

      if(timeNum > 1){
        if(this.planStartTime && this.planEndTime) this.checkCalendarClash();
      }


      this.receiptFields = result[1] || [];
      let richtextObjRecept_ = {};
      this.receiptFields.forEach(async (field, i) => {
        if(field.formType == 'richtext'){
          // 富文本信息需要从接口获取
          let { isSystem, fieldName } = field;
          let { receiptTaskForRead : receiptTaskForRead_ } = this.initData;
          let id = isSystem == 1 ? receiptTaskForRead_[fieldName] : receiptTaskForRead_.attribute[fieldName]
          if(id){
            richtextObjRecept_[id] = fieldName;
          }
          // let content_ = await getRichTextContent({
          //   ids:[id]
          // })
          // let richtextCon = '';
          // if(content_.code == 0){
          //   richtextCon = content_.result[0].content;
          // }
          // isSystem == 1 ? this.initData.receiptTaskForRead[fieldName] = richtextCon : this.initData.receiptTaskForRead.attribute[fieldName] = richtextCon
        }
      })
      let richtextIdsRecept = Object.keys(richtextObjRecept_) || [];
      if (richtextIdsRecept.length) {
        let content_ = await getRichTextContent({
          ids: richtextIdsRecept,
        });
        let richtextCon = '';
        if (content_.code == 0) {
          content_.result?.forEach((item, index) => {
            let key_ = richtextIdsRecept[index];
            let fieldName_ = richtextObjRecept_[key_];
            try {
              richtextCon = item.content;
            } catch (error) {
              console.warn(error, 'error try catch');
            }
            this.initData.receiptTaskForRead.attribute[fieldName_] = richtextCon
          });
        }
      }

      if(this.taskFlowExtend) {
        this.getAddonsBtn()
        // 查询自定义节点的负责人和已经办理过的人员
        await this.getCurrentNodeExecutor();
      }

      this.stateButtonData = this.buildButtonData();
      console.log(this.stateButtonData, 'stateButtonData')

      let query = parse(window.location.search) || {};

      // 来自审核结算列表的结算操作
      if (query.active == 'balance' && this.viewBalanceTab && this.allowBalanceTask) {
        setTimeout(() => {
          this.openDialog('balance');
        }, 1000);
      }else if (query.name == 'settlement') {
        this.openDialog('settlement');
      } else {
        // this.rightActiveTab = this.viewBalanceTab ? 'balance-tab' : this.viewFeedbackTab ? 'feedback-tab' : 'record';
      }
      this.isToReceiptView = query.isToReceiptView
      if(this.isToReceiptView) {
        // 回执信息改为右侧
        this.rightActiveTab = 'receipt-view'
      }
      // 是否显示详情向导
      this.showTaskDetailGuide = !storageGet(TASK_GUIDE_DETAIL)
      // 来自指派列表的指派操作
      this.showAllotModal = query.allot && this.allowAllotTask
      if (this.showAllotModal && !this.showTaskDetailGuide) {
        this.allot()
      }

      // 是否显示服务商结算tab

      this.$emit('changeLoading', false);

      // 获取是否有安装产品和安装位置 目前只有博立有数据 其它的数据为空
      const _res = await TaskApi.getExpensePartField()
      if (_res.code == 0) {
        this.partField = _res.result || []
      }
      await this.searchProvideSettleAuth();
      await this.initRightTabBar()

      if(location.hash === '#toReview') {
        this.$nextTick(() => {
          if (this.stateButtonData?.find(v => v.btnType === 'review')) {
            let el = this.$refs.currentStateButton?.querySelector('[data-btn-type=review]')
            el && el.click()
            location.hash = ''
          }
        })
      }

      const sparePartCardRef = findComponentDownward(this, 'spare-part-card') || {};
      this.sparePartCardList = (sparePartCardRef.data || []).filter(x => x.useNum > 0);

      // 进入页面清除缓存
      localStorage.removeItem(`set_curreny_key_${this.task.id}`)
      localStorage.removeItem(`set_manual_curreny_${this.task.id}`)
    } catch (e) {
      console.error(e)
    }
  },
  watch: {
    collapse(newValue) {
      sessionStorage.setItem(`task_customer_collapse_${this.task.id}`, newValue);
    },
    collapseDirection(newValue) {
      sessionStorage.setItem(`task_collapseDirection_${this.task.id}`, newValue);
    }
  },
  components: {
    [SettlementProviders.name]: SettlementProviders,
    [CancelTaskDialog.name]: CancelTaskDialog,
    [PlanTimeDialog.name]: PlanTimeDialog,
    [CalendarPlanTimeDialog.name]: CalendarPlanTimeDialog,
    [ApproveTaskDialog.name]: ApproveTaskDialog,
    [TaskApproveSignature.name]: TaskApproveSignature,
    [TaskAdvancedApprove.name]: TaskAdvancedApprove,
    [ProposeApproveDialog.name]: ProposeApproveDialog,
    [ServiceReportDialog.name]: ServiceReportDialog,
    [TaskInfoRecord.name]: TaskInfoRecord,
    [TaskReceiptView.name]: TaskReceiptView,
    [TaskReceiptEditView.name]: TaskReceiptEditView,
    [TaskAccount.name]: TaskAccount,
    [TaskFeedback.name]: TaskFeedback,
    [TaskProTab.name]: TaskProTab,
    [TaskCard.name]: TaskCard,
    [TaskView.name]: TaskView,
    [TaskTimeDialog.name]: TaskTimeDialog,
    TaskAllotModal,
    [WikiRecommend.name]: WikiRecommend,
    [TaskMaterialList.name]: TaskMaterialList,
    [NoDataViewNew.name]: NoDataViewNew,
    BaseBarV3,
    BaseTileLayoutTabBar,
    SelectUser,
    SettlementDialog,
    settlementTab,
    BbxTimezoneTimePicker,
    [FaultTable.name]: FaultTable,
  }
}
